// 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.retail.v2;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/retail/v2/common.proto";
import "google/cloud/retail/v2/search_service.proto";

option csharp_namespace = "Google.Cloud.Retail.V2";
option go_package = "cloud.google.com/go/retail/apiv2/retailpb;retailpb";
option java_multiple_files = true;
option java_outer_classname = "ServingConfigProto";
option java_package = "com.google.cloud.retail.v2";
option objc_class_prefix = "RETAIL";
option php_namespace = "Google\\Cloud\\Retail\\V2";
option ruby_package = "Google::Cloud::Retail::V2";

// Configures metadata that is used to generate serving time results (e.g.
// search results or recommendation predictions).
message ServingConfig {
  option (google.api.resource) = {
    type: "retail.googleapis.com/ServingConfig"
    pattern: "projects/{project}/locations/{location}/catalogs/{catalog}/servingConfigs/{serving_config}"
  };

  // What type of diversity - data or rule based.
  enum DiversityType {
    // Default value.
    DIVERSITY_TYPE_UNSPECIFIED = 0;

    // Rule based diversity.
    RULE_BASED_DIVERSITY = 2;

    // Data driven diversity.
    DATA_DRIVEN_DIVERSITY = 3;
  }

  // Immutable. Fully qualified name
  // `projects/*/locations/global/catalogs/*/servingConfig/*`
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // Required. The human readable serving config display name. Used in Retail
  // UI.
  //
  // This field must be a UTF-8 encoded string with a length limit of 128
  // characters. Otherwise, an INVALID_ARGUMENT error is returned.
  string display_name = 2 [(google.api.field_behavior) = REQUIRED];

  // The id of the model in the same [Catalog][google.cloud.retail.v2.Catalog]
  // to use at serving time. Currently only RecommendationModels are supported:
  // https://cloud.google.com/retail/recommendations-ai/docs/create-models
  // Can be changed but only to a compatible model (e.g.
  // others-you-may-like CTR to others-you-may-like CVR).
  //
  // Required when
  // [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
  // [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_RECOMMENDATION].
  string model_id = 3;

  // How much price ranking we want in serving results.
  // Price reranking causes product items with a similar
  // recommendation probability to be ordered by price, with the
  // highest-priced items first. This setting could result in a decrease in
  // click-through and conversion rates.
  //  Allowed values are:
  //
  // * `no-price-reranking`
  // * `low-price-reranking`
  // * `medium-price-reranking`
  // * `high-price-reranking`
  //
  // If not specified, we choose default based on model type. Default value:
  // `no-price-reranking`.
  //
  // Can only be set if
  // [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
  // [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_RECOMMENDATION].
  string price_reranking_level = 4;

  // Facet specifications for faceted search. If empty, no facets are returned.
  // The ids refer to the ids of [Control][google.cloud.retail.v2.Control]
  // resources with only the Facet control set. These controls are assumed to be
  // in the same [Catalog][google.cloud.retail.v2.Catalog] as the
  // [ServingConfig][google.cloud.retail.v2.ServingConfig].
  // A maximum of 100 values are allowed. Otherwise, an INVALID_ARGUMENT error
  // is returned.
  //
  // Can only be set if
  // [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
  // [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
  repeated string facet_control_ids = 5;

  // The specification for dynamically generated facets. Notice that only
  // textual facets can be dynamically generated.
  //
  // Can only be set if
  // [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
  // [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
  SearchRequest.DynamicFacetSpec dynamic_facet_spec = 6;

  // Condition boost specifications. If a product matches multiple conditions
  // in the specifications, boost scores from these specifications are all
  // applied and combined in a non-linear way. Maximum number of
  // specifications is 100.
  //
  // Notice that if both
  // [ServingConfig.boost_control_ids][google.cloud.retail.v2.ServingConfig.boost_control_ids]
  // and
  // [SearchRequest.boost_spec][google.cloud.retail.v2.SearchRequest.boost_spec]
  // are set, the boost conditions from both places are evaluated. If a search
  // request matches multiple boost conditions, the final boost score is equal
  // to the sum of the boost scores from all matched boost conditions.
  //
  // Can only be set if
  // [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
  // [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
  repeated string boost_control_ids = 7;

  // Condition filter specifications. If a product matches multiple conditions
  // in the specifications, filters from these specifications are all
  // applied and combined via the AND operator. Maximum number of
  // specifications is 100.
  //
  // Can only be set if
  // [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
  // [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
  repeated string filter_control_ids = 9;

  // Condition redirect specifications. Only the first triggered redirect action
  // is applied, even if multiple apply. Maximum number of specifications is
  // 1000.
  //
  // Can only be set if
  // [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
  // [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
  repeated string redirect_control_ids = 10;

  // Condition synonyms specifications. If multiple syonyms conditions match,
  // all matching synonyms control in the list will execute. Order of controls
  // in the list will not matter. Maximum number of specifications is
  // 100.
  //
  // Can only be set if
  // [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
  // [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
  repeated string twoway_synonyms_control_ids = 18;

  // Condition oneway synonyms specifications. If multiple oneway synonyms
  // conditions match, all matching oneway synonyms controls in the list will
  // execute. Order of controls in the list will not matter. Maximum number of
  // specifications is 100.
  //
  // Can only be set if
  // [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
  // [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
  repeated string oneway_synonyms_control_ids = 12;

  // Condition do not associate specifications. If multiple do not associate
  // conditions match, all matching do not associate controls in the list will
  // execute.
  // - Order does not matter.
  // - Maximum number of specifications is 100.
  //
  // Can only be set if
  // [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
  // [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
  repeated string do_not_associate_control_ids = 13;

  // Condition replacement specifications.
  // - Applied according to the order in the list.
  // - A previously replaced term can not be re-replaced.
  // - Maximum number of specifications is 100.
  //
  // Can only be set if
  // [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
  // [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
  repeated string replacement_control_ids = 14;

  // Condition ignore specifications. If multiple ignore
  // conditions match, all matching ignore controls in the list will
  // execute.
  // - Order does not matter.
  // - Maximum number of specifications is 100.
  //
  // Can only be set if
  // [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
  // [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
  repeated string ignore_control_ids = 15;

  // How much diversity to use in recommendation model results e.g.
  // `medium-diversity` or `high-diversity`. Currently supported values:
  //
  // * `no-diversity`
  // * `low-diversity`
  // * `medium-diversity`
  // * `high-diversity`
  // * `auto-diversity`
  //
  // If not specified, we choose default based on recommendation model
  // type. Default value: `no-diversity`.
  //
  // Can only be set if
  // [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
  // [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_RECOMMENDATION].
  string diversity_level = 8;

  // What kind of diversity to use - data driven or rule based. If unset, the
  // server behavior defaults to
  // [RULE_BASED_DIVERSITY][google.cloud.retail.v2.ServingConfig.DiversityType.RULE_BASED_DIVERSITY].
  DiversityType diversity_type = 20;

  // Whether to add additional category filters on the `similar-items` model.
  // If not specified, we enable it by default.
  //  Allowed values are:
  //
  // * `no-category-match`: No additional filtering of original results from
  //   the model and the customer's filters.
  // * `relaxed-category-match`: Only keep results with categories that match
  //   at least one item categories in the PredictRequests's context item.
  //   * If customer also sends filters in the PredictRequest, then the results
  //   will satisfy both conditions (user given and category match).
  //
  // Can only be set if
  // [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
  // [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_RECOMMENDATION].
  string enable_category_filter_level = 16;

  // When the flag is enabled, the products in the denylist will not be filtered
  // out in the recommendation filtering results.
  bool ignore_recs_denylist = 24;

  // The specification for personalization spec.
  //
  // Can only be set if
  // [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] is
  // [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH].
  //
  // Notice that if both
  // [ServingConfig.personalization_spec][google.cloud.retail.v2.ServingConfig.personalization_spec]
  // and
  // [SearchRequest.personalization_spec][google.cloud.retail.v2.SearchRequest.personalization_spec]
  // are set.
  // [SearchRequest.personalization_spec][google.cloud.retail.v2.SearchRequest.personalization_spec]
  // will override
  // [ServingConfig.personalization_spec][google.cloud.retail.v2.ServingConfig.personalization_spec].
  SearchRequest.PersonalizationSpec personalization_spec = 21;

  // Required. Immutable. Specifies the solution types that a serving config can
  // be associated with. Currently we support setting only one type of solution.
  repeated SolutionType solution_types = 19 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.field_behavior) = IMMUTABLE
  ];
}
