// Copyright 2020 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.v3;

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/v3/page.proto";
import "google/longrunning/operations.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";

option cc_enable_arenas = true;
option csharp_namespace = "Google.Cloud.Dialogflow.Cx.V3";
option go_package = "google.golang.org/genproto/googleapis/cloud/dialogflow/cx/v3;cx";
option java_multiple_files = true;
option java_outer_classname = "FlowProto";
option java_package = "com.google.cloud.dialogflow.cx.v3";
option objc_class_prefix = "DF";

// Service for managing [Flows][google.cloud.dialogflow.cx.v3.Flow].
service Flows {
  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";

  // Creates a flow in the specified agent.
  rpc CreateFlow(CreateFlowRequest) returns (Flow) {
    option (google.api.http) = {
      post: "/v3/{parent=projects/*/locations/*/agents/*}/flows"
      body: "flow"
    };
    option (google.api.method_signature) = "parent,flow";
  }

  // Deletes a specified flow.
  rpc DeleteFlow(DeleteFlowRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v3/{name=projects/*/locations/*/agents/*/flows/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Returns the list of all flows in the specified agent.
  rpc ListFlows(ListFlowsRequest) returns (ListFlowsResponse) {
    option (google.api.http) = {
      get: "/v3/{parent=projects/*/locations/*/agents/*}/flows"
    };
    option (google.api.method_signature) = "parent";
  }

  // Retrieves the specified flow.
  rpc GetFlow(GetFlowRequest) returns (Flow) {
    option (google.api.http) = {
      get: "/v3/{name=projects/*/locations/*/agents/*/flows/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Updates the specified flow.
  rpc UpdateFlow(UpdateFlowRequest) returns (Flow) {
    option (google.api.http) = {
      patch: "/v3/{flow.name=projects/*/locations/*/agents/*/flows/*}"
      body: "flow"
    };
    option (google.api.method_signature) = "flow,update_mask";
  }

  // Trains the specified flow. Note that only the flow in 'draft' environment
  // is trained.
  rpc TrainFlow(TrainFlowRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v3/{name=projects/*/locations/*/agents/*/flows/*}:train"
      body: "*"
    };
    option (google.api.method_signature) = "name";
    option (google.longrunning.operation_info) = {
      response_type: "google.protobuf.Empty"
      metadata_type: "google.protobuf.Struct"
    };
  }
}

// Settings related to NLU.
message NluSettings {
  // NLU model type.
  enum ModelType {
    // Not specified. `MODEL_TYPE_STANDARD` will be used.
    MODEL_TYPE_UNSPECIFIED = 0;

    // Use standard NLU model.
    MODEL_TYPE_STANDARD = 1;

    // Use advanced NLU model.
    MODEL_TYPE_ADVANCED = 3;
  }

  // NLU model training mode.
  enum ModelTrainingMode {
    // Not specified. `MODEL_TRAINING_MODE_AUTOMATIC` will be used.
    MODEL_TRAINING_MODE_UNSPECIFIED = 0;

    // NLU model training is automatically triggered when a flow gets modified.
    // User can also manually trigger model training in this mode.
    MODEL_TRAINING_MODE_AUTOMATIC = 1;

    // User needs to manually trigger NLU model training. Best for large flows
    // whose models take long time to train.
    MODEL_TRAINING_MODE_MANUAL = 2;
  }

  // Indicates the type of NLU model.
  ModelType model_type = 1;

  // To filter out false positive results and still get variety in matched
  // natural language inputs for your agent, you can tune the machine learning
  // classification threshold. If the returned score value is less than the
  // threshold value, then a no-match event will be triggered. The score values
  // range from 0.0 (completely uncertain) to 1.0 (completely certain). If set
  // to 0.0, the default of 0.3 is used.
  float classification_threshold = 3;

  // Indicates NLU model training mode.
  ModelTrainingMode model_training_mode = 4;
}

// Flows represents the conversation flows when you build your chatbot agent.
//
// A flow consists of many pages connected by the transition routes.
// Conversations always start with the built-in Start Flow (with an all-0 ID).
// Transition routes can direct the conversation session from the current flow
// (parent flow) to another flow (sub flow). When the sub flow is finished,
// Dialogflow will bring the session back to the parent flow, where the sub flow
// is started.
//
// Usually, when a transition route is followed by a matched intent, the intent
// will be "consumed". This means the intent won't activate more transition
// routes. However, when the followed transition route moves the conversation
// session into a different flow, the matched intent can be carried over and to
// be consumed in the target flow.
message Flow {
  option (google.api.resource) = {
    type: "dialogflow.googleapis.com/Flow"
    pattern: "projects/{project}/locations/{location}/agents/{agent}/flows/{flow}"
  };

  // The unique identifier of the flow.
  // Format: `projects/<Project ID>/locations/<Location ID>/agents/<Agent
  // ID>/flows/<Flow ID>`.
  string name = 1;

  // Required. The human-readable name of the flow.
  string display_name = 2 [(google.api.field_behavior) = REQUIRED];

  // The description of the flow. The maximum length is 500 characters. If
  // exceeded, the request is rejected.
  string description = 3;

  // A flow's transition routes serve two purposes:
  //
  // *   They are responsible for matching the user's first utterances in the
  // flow.
  // *   They are inherited by every page's [transition
  // routes][Page.transition_routes] and can support use cases such as the user
  // saying "help" or "can I talk to a human?", which can be handled in a common
  // way regardless of the current page. Transition routes defined in the page
  // have higher priority than those defined in the flow.
  //
  // TransitionRoutes are evalauted in the following order:
  //
  // *   TransitionRoutes with intent specified..
  // *   TransitionRoutes with only condition specified.
  //
  // TransitionRoutes with intent specified are inherited by pages in the flow.
  repeated TransitionRoute transition_routes = 4;

  // A flow's event handlers serve two purposes:
  //
  // *   They are responsible for handling events (e.g. no match,
  // webhook errors) in the flow.
  // *   They are inherited by every page's [event
  // handlers][Page.event_handlers], which can be used to handle common events
  // regardless of the current page. Event handlers defined in the page
  // have higher priority than those defined in the flow.
  //
  // Unlike [transition_routes][google.cloud.dialogflow.cx.v3.Flow.transition_routes], these handlers are
  // evaluated on a first-match basis. The first one that matches the event
  // get executed, with the rest being ignored.
  repeated EventHandler event_handlers = 10;

  // NLU related settings of the flow.
  NluSettings nlu_settings = 11;
}

// The request message for [Flows.CreateFlow][google.cloud.dialogflow.cx.v3.Flows.CreateFlow].
message CreateFlowRequest {
  // Required. The agent to create a flow for.
  // Format: `projects/<Project ID>/locations/<Location ID>/agents/<Agent ID>`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dialogflow.googleapis.com/Flow"
    }
  ];

  // Required. The flow to create.
  Flow flow = 2 [(google.api.field_behavior) = REQUIRED];

  // The language of the following fields in `flow`:
  //
  // *  `Flow.event_handlers.trigger_fulfillment.messages`
  // *  `Flow.transition_routes.trigger_fulfillment.messages`
  //
  // If not specified, the agent's default language is used.
  // [Many
  // languages](https://cloud.google.com/dialogflow/docs/reference/language)
  // are supported.
  // Note: languages must be enabled in the agent before they can be used.
  string language_code = 3;
}

// The request message for [Flows.DeleteFlow][google.cloud.dialogflow.cx.v3.Flows.DeleteFlow].
message DeleteFlowRequest {
  // Required. The name of the flow to delete.
  // Format: `projects/<Project ID>/locations/<Location ID>/agents/<Agent
  // ID>/flows/<Flow ID>`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dialogflow.googleapis.com/Flow"
    }
  ];

  // This field has no effect for flows with no incoming transitions.
  // For flows with incoming transitions:
  //
  // *  If `force` is set to false, an error will be returned with message
  //    indicating the incoming transitions.
  // *  If `force` is set to true, Dialogflow will remove the flow, as well as
  //    any transitions to the flow (i.e. [Target
  //    flow][EventHandler.target_flow] in event handlers or [Target
  //    flow][TransitionRoute.target_flow] in transition routes that point to
  //    this flow will be cleared).
  bool force = 2;
}

// The request message for [Flows.ListFlows][google.cloud.dialogflow.cx.v3.Flows.ListFlows].
message ListFlowsRequest {
  // Required. The agent containing the flows.
  // Format: `projects/<Project ID>/locations/<Location ID>/agents/<Agent ID>`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dialogflow.googleapis.com/Flow"
    }
  ];

  // The maximum number of items to return in a single page. By default 100 and
  // at most 1000.
  int32 page_size = 2;

  // The next_page_token value returned from a previous list request.
  string page_token = 3;

  // The language to list flows for. The following fields are language
  // dependent:
  //
  // *  `Flow.event_handlers.trigger_fulfillment.messages`
  // *  `Flow.transition_routes.trigger_fulfillment.messages`
  //
  // If not specified, the agent's default language is used.
  // [Many
  // languages](https://cloud.google.com/dialogflow/docs/reference/language)
  // are supported.
  // Note: languages must be enabled in the agent before they can be used.
  string language_code = 4;
}

// The response message for [Flows.ListFlows][google.cloud.dialogflow.cx.v3.Flows.ListFlows].
message ListFlowsResponse {
  // The list of flows. There will be a maximum number of items returned based
  // on the page_size field in the request.
  repeated Flow flows = 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;
}

// The response message for [Flows.GetFlow][google.cloud.dialogflow.cx.v3.Flows.GetFlow].
message GetFlowRequest {
  // Required. The name of the flow to get.
  // Format: `projects/<Project ID>/locations/<Location ID>/agents/<Agent
  // ID>/flows/<Flow ID>`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dialogflow.googleapis.com/Flow"
    }
  ];

  // The language to retrieve the flow for. The following fields are language
  // dependent:
  //
  // *  `Flow.event_handlers.trigger_fulfillment.messages`
  // *  `Flow.transition_routes.trigger_fulfillment.messages`
  //
  // If not specified, the agent's default language is used.
  // [Many
  // languages](https://cloud.google.com/dialogflow/docs/reference/language)
  // are supported.
  // Note: languages must be enabled in the agent before they can be used.
  string language_code = 2;
}

// The request message for [Flows.UpdateFlow][google.cloud.dialogflow.cx.v3.Flows.UpdateFlow].
message UpdateFlowRequest {
  // Required. The flow to update.
  Flow flow = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The mask to control which fields get updated. If `update_mask` is not
  // specified, an error will be returned.
  google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = REQUIRED];

  // The language of the following fields in `flow`:
  //
  // *  `Flow.event_handlers.trigger_fulfillment.messages`
  // *  `Flow.transition_routes.trigger_fulfillment.messages`
  //
  // If not specified, the agent's default language is used.
  // [Many
  // languages](https://cloud.google.com/dialogflow/docs/reference/language)
  // are supported.
  // Note: languages must be enabled in the agent before they can be used.
  string language_code = 3;
}

// The request message for [Flows.TrainFlow][google.cloud.dialogflow.cx.v3.Flows.TrainFlow].
message TrainFlowRequest {
  // Required. The flow to train.
  // Format: `projects/<Project ID>/locations/<Location ID>/agents/<Agent
  // ID>/flows/<Flow ID>`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dialogflow.googleapis.com/Flow"
    }
  ];
}
