// 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.discoveryengine.v1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/discoveryengine/v1/assist_answer.proto";
import "google/cloud/discoveryengine/v1/search_service.proto";
import "google/cloud/discoveryengine/v1/session.proto";

option csharp_namespace = "Google.Cloud.DiscoveryEngine.V1";
option go_package = "cloud.google.com/go/discoveryengine/apiv1/discoveryenginepb;discoveryenginepb";
option java_multiple_files = true;
option java_outer_classname = "AssistantServiceProto";
option java_package = "com.google.cloud.discoveryengine.v1";
option objc_class_prefix = "DISCOVERYENGINE";
option php_namespace = "Google\\Cloud\\DiscoveryEngine\\V1";
option ruby_package = "Google::Cloud::DiscoveryEngine::V1";

// Service for managing Assistant configuration and assisting users.
service AssistantService {
  option (google.api.default_host) = "discoveryengine.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform";

  // Assists the user with a query in a streaming fashion.
  rpc StreamAssist(StreamAssistRequest) returns (stream StreamAssistResponse) {
    option (google.api.http) = {
      post: "/v1/{name=projects/*/locations/*/collections/*/engines/*/assistants/*}:streamAssist"
      body: "*"
    };
  }
}

// User metadata of the request.
message AssistUserMetadata {
  // Optional. IANA time zone, e.g. Europe/Budapest.
  string time_zone = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Preferred language to be used for answering if language detection
  // fails. Also used as the language of error messages created by actions,
  // regardless of language detection results.
  string preferred_language_code = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Request for the
// [AssistantService.StreamAssist][google.cloud.discoveryengine.v1.AssistantService.StreamAssist]
// method.
message StreamAssistRequest {
  // Specification of tools that are used to serve the request.
  message ToolsSpec {
    // Specification of the Vertex AI Search tool.
    message VertexAiSearchSpec {
      // Optional. Specs defining
      // [DataStore][google.cloud.discoveryengine.v1.DataStore]s to filter on in
      // a search call and configurations for those data stores. This is only
      // considered for [Engine][google.cloud.discoveryengine.v1.Engine]s with
      // multiple data stores.
      repeated SearchRequest.DataStoreSpec data_store_specs = 2
          [(google.api.field_behavior) = OPTIONAL];

      // Optional. The filter syntax consists of an expression language for
      // constructing a predicate from one or more fields of the documents being
      // filtered. Filter expression is case-sensitive.
      //
      // If this field is unrecognizable, an  `INVALID_ARGUMENT`  is returned.
      //
      // Filtering in Vertex AI Search is done by mapping the LHS filter key to
      // a key property defined in the Vertex AI Search backend -- this mapping
      // is defined by the customer in their schema. For example a media
      // customer might have a field 'name' in their schema. In this case the
      // filter would look like this: filter --> name:'ANY("king kong")'
      //
      // For more information about filtering including syntax and filter
      // operators, see
      // [Filter](https://cloud.google.com/generative-ai-app-builder/docs/filter-search-metadata)
      string filter = 4 [(google.api.field_behavior) = OPTIONAL];
    }

    // Specification of the web grounding tool.
    message WebGroundingSpec {}

    // Specification of the image generation tool.
    message ImageGenerationSpec {}

    // Specification of the video generation tool.
    message VideoGenerationSpec {}

    // Optional. Specification of the Vertex AI Search tool.
    VertexAiSearchSpec vertex_ai_search_spec = 1
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Specification of the web grounding tool.
    // If field is present, enables grounding with web search. Works only if
    // [Assistant.web_grounding_type][google.cloud.discoveryengine.v1.Assistant.web_grounding_type]
    // is [WEB_GROUNDING_TYPE_GOOGLE_SEARCH][] or
    // [WEB_GROUNDING_TYPE_ENTERPRISE_WEB_SEARCH][].
    WebGroundingSpec web_grounding_spec = 2
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Specification of the image generation tool.
    ImageGenerationSpec image_generation_spec = 3
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Specification of the video generation tool.
    VideoGenerationSpec video_generation_spec = 4
        [(google.api.field_behavior) = OPTIONAL];
  }

  // Assistant generation specification for the request.
  // This allows to override the default generation configuration at the engine
  // level.
  message GenerationSpec {
    // Optional. The Vertex AI model_id used for the generative model. If not
    // set, the default Assistant model will be used.
    string model_id = 1 [(google.api.field_behavior) = OPTIONAL];
  }

  // Required. The resource name of the
  // [Assistant][google.cloud.discoveryengine.v1.Assistant]. Format:
  // `projects/{project}/locations/{location}/collections/{collection}/engines/{engine}/assistants/{assistant}`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "discoveryengine.googleapis.com/Assistant"
    }
  ];

  // Optional. Current user query.
  //
  // Empty query is only supported if `file_ids` are provided. In this case, the
  // answer will be generated based on those context files.
  Query query = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The session to use for the request. If specified, the assistant
  // has access to the session history, and the query and the answer are stored
  // there.
  //
  // If `-` is specified as the session ID, or it is left empty, then a new
  // session is created with an automatically generated ID.
  //
  // Format:
  // `projects/{project}/locations/{location}/collections/{collection}/engines/{engine}/sessions/{session}`
  string session = 3 [
    (google.api.field_behavior) = OPTIONAL,
    (google.api.resource_reference) = {
      type: "discoveryengine.googleapis.com/Session"
    }
  ];

  // Optional. Information about the user initiating the query.
  AssistUserMetadata user_metadata = 6 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Specification of tools that are used to serve the request.
  ToolsSpec tools_spec = 18 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Specification of the generation configuration for the request.
  GenerationSpec generation_spec = 19 [(google.api.field_behavior) = OPTIONAL];
}

// Response for the
// [AssistantService.StreamAssist][google.cloud.discoveryengine.v1.AssistantService.StreamAssist]
// method.
message StreamAssistResponse {
  // Information about the session.
  message SessionInfo {
    // Name of the newly generated or continued session.
    //
    // Format:
    // `projects/{project}/locations/{location}/collections/{collection}/engines/{engine}/sessions/{session}`.
    string session = 1 [(google.api.resource_reference) = {
      type: "discoveryengine.googleapis.com/Session"
    }];
  }

  // Assist answer resource object containing parts of the assistant's final
  // answer for the user's query.
  //
  // Not present if the current response doesn't add anything to previously
  // sent
  // [AssistAnswer.replies][google.cloud.discoveryengine.v1.AssistAnswer.replies].
  //
  // Observe
  // [AssistAnswer.state][google.cloud.discoveryengine.v1.AssistAnswer.state] to
  // see if more parts are to be expected. While the state is `IN_PROGRESS`, the
  // [AssistAnswer.replies][google.cloud.discoveryengine.v1.AssistAnswer.replies]
  // field in each response will contain replies (reply fragments) to be
  // appended to the ones received in previous responses. [AssistAnswer.name][]
  // won't be filled.
  //
  // If the state is `SUCCEEDED`, `FAILED` or `SKIPPED`, the response
  // is the last response and [AssistAnswer.name][] will have a value.
  AssistAnswer answer = 1;

  // Session information.
  SessionInfo session_info = 2;

  // A global unique ID that identifies the current pair of request and stream
  // of responses. Used for feedback and support.
  string assist_token = 4;
}
