// 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/generative_settings.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.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 = "GeneratorProto";
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
// [Generators][google.cloud.dialogflow.cx.v3beta1.Generator]
service Generators {
  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 generators in the specified agent.
  rpc ListGenerators(ListGeneratorsRequest) returns (ListGeneratorsResponse) {
    option (google.api.http) = {
      get: "/v3beta1/{parent=projects/*/locations/*/agents/*}/generators"
    };
    option (google.api.method_signature) = "parent";
  }

  // Retrieves the specified generator.
  rpc GetGenerator(GetGeneratorRequest) returns (Generator) {
    option (google.api.http) = {
      get: "/v3beta1/{name=projects/*/locations/*/agents/*/generators/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Creates a generator in the specified agent.
  rpc CreateGenerator(CreateGeneratorRequest) returns (Generator) {
    option (google.api.http) = {
      post: "/v3beta1/{parent=projects/*/locations/*/agents/*}/generators"
      body: "generator"
    };
    option (google.api.method_signature) = "parent,generator";
  }

  // Update the specified generator.
  rpc UpdateGenerator(UpdateGeneratorRequest) returns (Generator) {
    option (google.api.http) = {
      patch: "/v3beta1/{generator.name=projects/*/locations/*/agents/*/generators/*}"
      body: "generator"
    };
    option (google.api.method_signature) = "generator,update_mask";
  }

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

// Generators contain prompt to be sent to the LLM model to generate text. The
// prompt can contain parameters which will be resolved before calling the
// model. It can optionally contain banned phrases to ensure the model responses
// are safe.
message Generator {
  option (google.api.resource) = {
    type: "dialogflow.googleapis.com/Generator"
    pattern: "projects/{project}/locations/{location}/agents/{agent}/generators/{generator}"
  };

  // Represents a custom placeholder in the prompt text.
  message Placeholder {
    // Unique ID used to map custom placeholder to parameters in fulfillment.
    string id = 1;

    // Custom placeholder value in the prompt text.
    string name = 2;
  }

  // Parameters to be passed to the LLM. If not set, default values will be
  // used.
  message ModelParameter {
    // The temperature used for sampling. Temperature sampling occurs after both
    // topP and topK have been applied.
    // Valid range: [0.0, 1.0]
    // Low temperature = less random. High temperature = more random.
    optional float temperature = 1;

    // The maximum number of tokens to generate.
    optional int32 max_decode_steps = 2;

    // If set, only the tokens comprising the top top_p probability mass are
    // considered. If both top_p and top_k are
    // set, top_p will be used for further refining candidates selected with
    // top_k.
    // Valid range: (0.0, 1.0].
    // Small topP = less random. Large topP = more random.
    optional float top_p = 3;

    // If set, the sampling process in each step is limited to the top_k tokens
    // with highest probabilities.
    // Valid range: [1, 40] or 1000+.
    // Small topK = less random. Large topK = more random.
    optional int32 top_k = 4;
  }

  // The unique identifier of the generator.
  // Must be set for the
  // [Generators.UpdateGenerator][google.cloud.dialogflow.cx.v3beta1.Generators.UpdateGenerator]
  // method. [Generators.CreateGenerate][] populates the name automatically.
  // Format:
  // `projects/<ProjectID>/locations/<LocationID>/agents/<AgentID>/generators/<GeneratorID>`.
  string name = 1;

  // Required. The human-readable name of the generator, unique within the
  // agent. The prompt contains pre-defined parameters such as $conversation,
  // $last-user-utterance, etc. populated by Dialogflow. It can also contain
  // custom placeholders which will be resolved during fulfillment.
  string display_name = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Prompt for the LLM model.
  Phrase prompt_text = 3 [(google.api.field_behavior) = REQUIRED];

  // Optional. List of custom placeholders in the prompt text.
  repeated Placeholder placeholders = 5
      [(google.api.field_behavior) = OPTIONAL];

  // The LLM model settings.
  LlmModelSettings llm_model_settings = 9;

  // Parameters passed to the LLM to configure its behavior.
  ModelParameter model_parameter = 8;
}

// Text input which can be used for prompt or banned phrases.
message Phrase {
  // Required. Text input which can be used for prompt or banned phrases.
  string text = 1 [(google.api.field_behavior) = REQUIRED];
}

// The request message for
// [Generators.ListGenerators][google.cloud.dialogflow.cx.v3beta1.Generators.ListGenerators].
message ListGeneratorsRequest {
  // Required. The agent to list all generators 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/Generator"
    }
  ];

  // The language to list generators for.
  string language_code = 2;

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

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

// The response message for
// [Generators.ListGenerators][google.cloud.dialogflow.cx.v3beta1.Generators.ListGenerators].
message ListGeneratorsResponse {
  // The list of generators. There will be a maximum number of items returned
  // based on the page_size field in the request.
  repeated Generator generators = 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 request message for
// [Generators.GetGenerator][google.cloud.dialogflow.cx.v3beta1.Generators.GetGenerator].
message GetGeneratorRequest {
  // Required. The name of the generator.
  // Format:
  // `projects/<ProjectID>/locations/<LocationID>/agents/<AgentID>/generators/<GeneratorID>`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dialogflow.googleapis.com/Generator"
    }
  ];

  // The language to list generators for.
  string language_code = 2;
}

// The request message for
// [Generators.CreateGenerator][google.cloud.dialogflow.cx.v3beta1.Generators.CreateGenerator].
message CreateGeneratorRequest {
  // Required. The agent to create a generator 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/Generator"
    }
  ];

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

  // The language to create generators for the following fields:
  // *  `Generator.prompt_text.text`
  // If not specified, the agent's default language is used.
  string language_code = 3;
}

// The request message for
// [Generators.UpdateGenerator][google.cloud.dialogflow.cx.v3beta1.Generators.UpdateGenerator].
message UpdateGeneratorRequest {
  // Required. The generator to update.
  Generator generator = 1 [(google.api.field_behavior) = REQUIRED];

  // The language to list generators for.
  string language_code = 2;

  // The mask to control which fields get updated. If the mask is not present,
  // all fields will be updated.
  google.protobuf.FieldMask update_mask = 3;
}

// The request message for
// [Generators.DeleteGenerator][google.cloud.dialogflow.cx.v3beta1.Generators.DeleteGenerator].
message DeleteGeneratorRequest {
  // Required. The name of the generator to delete.
  // Format:
  // `projects/<ProjectID>/locations/<LocationID>/agents/<AgentID>/generators/<GeneratorID>`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dialogflow.googleapis.com/Generator"
    }
  ];

  // This field has no effect for generators not being used.
  // For generators that are used by pages/flows/transition route groups:
  //
  // *  If `force` is set to false, an error will be returned with message
  //    indicating the referenced resources.
  // *  If `force` is set to true, Dialogflow will remove the generator, as well
  //    as any references to the generator (i.e.
  //    [Generator][Fulfillment.generator]) in fulfillments.
  bool force = 2;
}
