// Copyright 2024 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.ai.generativelanguage.v1alpha;

import "google/ai/generativelanguage/v1alpha/retriever.proto";
import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";

option go_package = "cloud.google.com/go/ai/generativelanguage/apiv1alpha/generativelanguagepb;generativelanguagepb";
option java_multiple_files = true;
option java_outer_classname = "RetrieverServiceProto";
option java_package = "com.google.ai.generativelanguage.v1alpha";

// An API for semantic search over a corpus of user uploaded content.
service RetrieverService {
  option (google.api.default_host) = "generativelanguage.googleapis.com";

  // Creates an empty `Corpus`.
  rpc CreateCorpus(CreateCorpusRequest) returns (Corpus) {
    option (google.api.http) = {
      post: "/v1alpha/corpora"
      body: "corpus"
    };
    option (google.api.method_signature) = "corpus";
  }

  // Gets information about a specific `Corpus`.
  rpc GetCorpus(GetCorpusRequest) returns (Corpus) {
    option (google.api.http) = {
      get: "/v1alpha/{name=corpora/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Updates a `Corpus`.
  rpc UpdateCorpus(UpdateCorpusRequest) returns (Corpus) {
    option (google.api.http) = {
      patch: "/v1alpha/{corpus.name=corpora/*}"
      body: "corpus"
    };
    option (google.api.method_signature) = "corpus,update_mask";
  }

  // Deletes a `Corpus`.
  rpc DeleteCorpus(DeleteCorpusRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1alpha/{name=corpora/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Lists all `Corpora` owned by the user.
  rpc ListCorpora(ListCorporaRequest) returns (ListCorporaResponse) {
    option (google.api.http) = {
      get: "/v1alpha/corpora"
    };
  }

  // Performs semantic search over a `Corpus`.
  rpc QueryCorpus(QueryCorpusRequest) returns (QueryCorpusResponse) {
    option (google.api.http) = {
      post: "/v1alpha/{name=corpora/*}:query"
      body: "*"
    };
  }

  // Creates an empty `Document`.
  rpc CreateDocument(CreateDocumentRequest) returns (Document) {
    option (google.api.http) = {
      post: "/v1alpha/{parent=corpora/*}/documents"
      body: "document"
    };
    option (google.api.method_signature) = "parent,document";
  }

  // Gets information about a specific `Document`.
  rpc GetDocument(GetDocumentRequest) returns (Document) {
    option (google.api.http) = {
      get: "/v1alpha/{name=corpora/*/documents/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Updates a `Document`.
  rpc UpdateDocument(UpdateDocumentRequest) returns (Document) {
    option (google.api.http) = {
      patch: "/v1alpha/{document.name=corpora/*/documents/*}"
      body: "document"
    };
    option (google.api.method_signature) = "document,update_mask";
  }

  // Deletes a `Document`.
  rpc DeleteDocument(DeleteDocumentRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1alpha/{name=corpora/*/documents/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Lists all `Document`s in a `Corpus`.
  rpc ListDocuments(ListDocumentsRequest) returns (ListDocumentsResponse) {
    option (google.api.http) = {
      get: "/v1alpha/{parent=corpora/*}/documents"
    };
    option (google.api.method_signature) = "parent";
  }

  // Performs semantic search over a `Document`.
  rpc QueryDocument(QueryDocumentRequest) returns (QueryDocumentResponse) {
    option (google.api.http) = {
      post: "/v1alpha/{name=corpora/*/documents/*}:query"
      body: "*"
    };
  }

  // Creates a `Chunk`.
  rpc CreateChunk(CreateChunkRequest) returns (Chunk) {
    option (google.api.http) = {
      post: "/v1alpha/{parent=corpora/*/documents/*}/chunks"
      body: "chunk"
    };
    option (google.api.method_signature) = "parent,chunk";
  }

  // Batch create `Chunk`s.
  rpc BatchCreateChunks(BatchCreateChunksRequest)
      returns (BatchCreateChunksResponse) {
    option (google.api.http) = {
      post: "/v1alpha/{parent=corpora/*/documents/*}/chunks:batchCreate"
      body: "*"
    };
  }

  // Gets information about a specific `Chunk`.
  rpc GetChunk(GetChunkRequest) returns (Chunk) {
    option (google.api.http) = {
      get: "/v1alpha/{name=corpora/*/documents/*/chunks/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Updates a `Chunk`.
  rpc UpdateChunk(UpdateChunkRequest) returns (Chunk) {
    option (google.api.http) = {
      patch: "/v1alpha/{chunk.name=corpora/*/documents/*/chunks/*}"
      body: "chunk"
    };
    option (google.api.method_signature) = "chunk,update_mask";
  }

  // Batch update `Chunk`s.
  rpc BatchUpdateChunks(BatchUpdateChunksRequest)
      returns (BatchUpdateChunksResponse) {
    option (google.api.http) = {
      post: "/v1alpha/{parent=corpora/*/documents/*}/chunks:batchUpdate"
      body: "*"
    };
  }

  // Deletes a `Chunk`.
  rpc DeleteChunk(DeleteChunkRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1alpha/{name=corpora/*/documents/*/chunks/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Batch delete `Chunk`s.
  rpc BatchDeleteChunks(BatchDeleteChunksRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      post: "/v1alpha/{parent=corpora/*/documents/*}/chunks:batchDelete"
      body: "*"
    };
  }

  // Lists all `Chunk`s in a `Document`.
  rpc ListChunks(ListChunksRequest) returns (ListChunksResponse) {
    option (google.api.http) = {
      get: "/v1alpha/{parent=corpora/*/documents/*}/chunks"
    };
    option (google.api.method_signature) = "parent";
  }
}

// Request to create a `Corpus`.
message CreateCorpusRequest {
  // Required. The `Corpus` to create.
  Corpus corpus = 1 [(google.api.field_behavior) = REQUIRED];
}

// Request for getting information about a specific `Corpus`.
message GetCorpusRequest {
  // Required. The name of the `Corpus`.
  // Example: `corpora/my-corpus-123`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "generativelanguage.googleapis.com/Corpus"
    }
  ];
}

// Request to update a `Corpus`.
message UpdateCorpusRequest {
  // Required. The `Corpus` to update.
  Corpus corpus = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The list of fields to update.
  // Currently, this only supports updating `display_name`.
  google.protobuf.FieldMask update_mask = 2
      [(google.api.field_behavior) = REQUIRED];
}

// Request to delete a `Corpus`.
message DeleteCorpusRequest {
  // Required. The resource name of the `Corpus`.
  // Example: `corpora/my-corpus-123`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "generativelanguage.googleapis.com/Corpus"
    }
  ];

  // Optional. If set to true, any `Document`s and objects related to this
  // `Corpus` will also be deleted.
  //
  // If false (the default), a `FAILED_PRECONDITION` error will be returned if
  // `Corpus` contains any `Document`s.
  bool force = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Request for listing `Corpora`.
message ListCorporaRequest {
  // Optional. The maximum number of `Corpora` to return (per page).
  // The service may return fewer `Corpora`.
  //
  // If unspecified, at most 10 `Corpora` will be returned.
  // The maximum size limit is 20 `Corpora` per page.
  int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A page token, received from a previous `ListCorpora` call.
  //
  // Provide the `next_page_token` returned in the response as an argument to
  // the next request to retrieve the next page.
  //
  // When paginating, all other parameters provided to `ListCorpora`
  // must match the call that provided the page token.
  string page_token = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Response from `ListCorpora` containing a paginated list of `Corpora`.
// The results are sorted by ascending `corpus.create_time`.
message ListCorporaResponse {
  // The returned corpora.
  repeated Corpus corpora = 1;

  // A token, which can be sent as `page_token` to retrieve the next page.
  // If this field is omitted, there are no more pages.
  string next_page_token = 2;
}

// Request for querying a `Corpus`.
message QueryCorpusRequest {
  // Required. The name of the `Corpus` to query.
  // Example: `corpora/my-corpus-123`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "generativelanguage.googleapis.com/Corpus"
    }
  ];

  // Required. Query string to perform semantic search.
  string query = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. Filter for `Chunk` and `Document` metadata. Each `MetadataFilter`
  // object should correspond to a unique key. Multiple `MetadataFilter` objects
  // are joined by logical "AND"s.
  //
  // Example query at document level:
  // (year >= 2020 OR year < 2010) AND (genre = drama OR genre = action)
  //
  // `MetadataFilter` object list:
  //  metadata_filters = [
  //  {key = "document.custom_metadata.year"
  //   conditions = [{int_value = 2020, operation = GREATER_EQUAL},
  //                 {int_value = 2010, operation = LESS}]},
  //  {key = "document.custom_metadata.year"
  //   conditions = [{int_value = 2020, operation = GREATER_EQUAL},
  //                 {int_value = 2010, operation = LESS}]},
  //  {key = "document.custom_metadata.genre"
  //   conditions = [{string_value = "drama", operation = EQUAL},
  //                 {string_value = "action", operation = EQUAL}]}]
  //
  // Example query at chunk level for a numeric range of values:
  // (year > 2015 AND year <= 2020)
  //
  // `MetadataFilter` object list:
  //  metadata_filters = [
  //  {key = "chunk.custom_metadata.year"
  //   conditions = [{int_value = 2015, operation = GREATER}]},
  //  {key = "chunk.custom_metadata.year"
  //   conditions = [{int_value = 2020, operation = LESS_EQUAL}]}]
  //
  // Note: "AND"s for the same key are only supported for numeric values. String
  // values only support "OR"s for the same key.
  repeated MetadataFilter metadata_filters = 3
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. The maximum number of `Chunk`s to return.
  // The service may return fewer `Chunk`s.
  //
  // If unspecified, at most 10 `Chunk`s will be returned.
  // The maximum specified result count is 100.
  int32 results_count = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Response from `QueryCorpus` containing a list of relevant chunks.
message QueryCorpusResponse {
  // The relevant chunks.
  repeated RelevantChunk relevant_chunks = 1;
}

// The information for a chunk relevant to a query.
message RelevantChunk {
  // `Chunk` relevance to the query.
  float chunk_relevance_score = 1;

  // `Chunk` associated with the query.
  Chunk chunk = 2;
}

// Request to create a `Document`.
message CreateDocumentRequest {
  // Required. The name of the `Corpus` where this `Document` will be created.
  // Example: `corpora/my-corpus-123`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "generativelanguage.googleapis.com/Document"
    }
  ];

  // Required. The `Document` to create.
  Document document = 2 [(google.api.field_behavior) = REQUIRED];
}

// Request for getting information about a specific `Document`.
message GetDocumentRequest {
  // Required. The name of the `Document` to retrieve.
  // Example: `corpora/my-corpus-123/documents/the-doc-abc`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "generativelanguage.googleapis.com/Document"
    }
  ];
}

// Request to update a `Document`.
message UpdateDocumentRequest {
  // Required. The `Document` to update.
  Document document = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The list of fields to update.
  // Currently, this only supports updating `display_name` and
  // `custom_metadata`.
  google.protobuf.FieldMask update_mask = 2
      [(google.api.field_behavior) = REQUIRED];
}

// Request to delete a `Document`.
message DeleteDocumentRequest {
  // Required. The resource name of the `Document` to delete.
  // Example: `corpora/my-corpus-123/documents/the-doc-abc`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "generativelanguage.googleapis.com/Document"
    }
  ];

  // Optional. If set to true, any `Chunk`s and objects related to this
  // `Document` will also be deleted.
  //
  // If false (the default), a `FAILED_PRECONDITION` error will be returned if
  // `Document` contains any `Chunk`s.
  bool force = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Request for listing `Document`s.
message ListDocumentsRequest {
  // Required. The name of the `Corpus` containing `Document`s.
  // Example: `corpora/my-corpus-123`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "generativelanguage.googleapis.com/Document"
    }
  ];

  // Optional. The maximum number of `Document`s to return (per page).
  // The service may return fewer `Document`s.
  //
  // If unspecified, at most 10 `Document`s will be returned.
  // The maximum size limit is 20 `Document`s per page.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A page token, received from a previous `ListDocuments` call.
  //
  // Provide the `next_page_token` returned in the response as an argument to
  // the next request to retrieve the next page.
  //
  // When paginating, all other parameters provided to `ListDocuments`
  // must match the call that provided the page token.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Response from `ListDocuments` containing a paginated list of `Document`s.
// The `Document`s are sorted by ascending `document.create_time`.
message ListDocumentsResponse {
  // The returned `Document`s.
  repeated Document documents = 1;

  // A token, which can be sent as `page_token` to retrieve the next page.
  // If this field is omitted, there are no more pages.
  string next_page_token = 2;
}

// Request for querying a `Document`.
message QueryDocumentRequest {
  // Required. The name of the `Document` to query.
  // Example: `corpora/my-corpus-123/documents/the-doc-abc`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "generativelanguage.googleapis.com/Document"
    }
  ];

  // Required. Query string to perform semantic search.
  string query = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. The maximum number of `Chunk`s to return.
  // The service may return fewer `Chunk`s.
  //
  // If unspecified, at most 10 `Chunk`s will be returned.
  // The maximum specified result count is 100.
  int32 results_count = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Filter for `Chunk` metadata. Each `MetadataFilter` object should
  // correspond to a unique key. Multiple `MetadataFilter` objects are joined by
  // logical "AND"s.
  //
  // Note: `Document`-level filtering is not supported for this request because
  // a `Document` name is already specified.
  //
  // Example query:
  // (year >= 2020 OR year < 2010) AND (genre = drama OR genre = action)
  //
  // `MetadataFilter` object list:
  //  metadata_filters = [
  //  {key = "chunk.custom_metadata.year"
  //   conditions = [{int_value = 2020, operation = GREATER_EQUAL},
  //                 {int_value = 2010, operation = LESS}},
  //  {key = "chunk.custom_metadata.genre"
  //   conditions = [{string_value = "drama", operation = EQUAL},
  //                 {string_value = "action", operation = EQUAL}}]
  //
  // Example query for a numeric range of values:
  // (year > 2015 AND year <= 2020)
  //
  // `MetadataFilter` object list:
  //  metadata_filters = [
  //  {key = "chunk.custom_metadata.year"
  //   conditions = [{int_value = 2015, operation = GREATER}]},
  //  {key = "chunk.custom_metadata.year"
  //   conditions = [{int_value = 2020, operation = LESS_EQUAL}]}]
  //
  // Note: "AND"s for the same key are only supported for numeric values. String
  // values only support "OR"s for the same key.
  repeated MetadataFilter metadata_filters = 4
      [(google.api.field_behavior) = OPTIONAL];
}

// Response from `QueryDocument` containing a list of relevant chunks.
message QueryDocumentResponse {
  // The returned relevant chunks.
  repeated RelevantChunk relevant_chunks = 1;
}

// Request to create a `Chunk`.
message CreateChunkRequest {
  // Required. The name of the `Document` where this `Chunk` will be created.
  // Example: `corpora/my-corpus-123/documents/the-doc-abc`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "generativelanguage.googleapis.com/Chunk"
    }
  ];

  // Required. The `Chunk` to create.
  Chunk chunk = 2 [(google.api.field_behavior) = REQUIRED];
}

// Request to batch create `Chunk`s.
message BatchCreateChunksRequest {
  // Optional. The name of the `Document` where this batch of `Chunk`s will be
  // created. The parent field in every `CreateChunkRequest` must match this
  // value. Example: `corpora/my-corpus-123/documents/the-doc-abc`
  string parent = 1 [
    (google.api.field_behavior) = OPTIONAL,
    (google.api.resource_reference) = {
      child_type: "generativelanguage.googleapis.com/Chunk"
    }
  ];

  // Required. The request messages specifying the `Chunk`s to create.
  // A maximum of 100 `Chunk`s can be created in a batch.
  repeated CreateChunkRequest requests = 2
      [(google.api.field_behavior) = REQUIRED];
}

// Response from `BatchCreateChunks` containing a list of created `Chunk`s.
message BatchCreateChunksResponse {
  // `Chunk`s created.
  repeated Chunk chunks = 1;
}

// Request for getting information about a specific `Chunk`.
message GetChunkRequest {
  // Required. The name of the `Chunk` to retrieve.
  // Example: `corpora/my-corpus-123/documents/the-doc-abc/chunks/some-chunk`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "generativelanguage.googleapis.com/Chunk"
    }
  ];
}

// Request to update a `Chunk`.
message UpdateChunkRequest {
  // Required. The `Chunk` to update.
  Chunk chunk = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The list of fields to update.
  // Currently, this only supports updating `custom_metadata` and `data`.
  google.protobuf.FieldMask update_mask = 2
      [(google.api.field_behavior) = REQUIRED];
}

// Request to batch update `Chunk`s.
message BatchUpdateChunksRequest {
  // Optional. The name of the `Document` containing the `Chunk`s to update.
  // The parent field in every `UpdateChunkRequest` must match this value.
  // Example: `corpora/my-corpus-123/documents/the-doc-abc`
  string parent = 1 [
    (google.api.field_behavior) = OPTIONAL,
    (google.api.resource_reference) = {
      child_type: "generativelanguage.googleapis.com/Chunk"
    }
  ];

  // Required. The request messages specifying the `Chunk`s to update.
  // A maximum of 100 `Chunk`s can be updated in a batch.
  repeated UpdateChunkRequest requests = 2
      [(google.api.field_behavior) = REQUIRED];
}

// Response from `BatchUpdateChunks` containing a list of updated `Chunk`s.
message BatchUpdateChunksResponse {
  // `Chunk`s updated.
  repeated Chunk chunks = 1;
}

// Request to delete a `Chunk`.
message DeleteChunkRequest {
  // Required. The resource name of the `Chunk` to delete.
  // Example: `corpora/my-corpus-123/documents/the-doc-abc/chunks/some-chunk`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "generativelanguage.googleapis.com/Chunk"
    }
  ];
}

// Request to batch delete `Chunk`s.
message BatchDeleteChunksRequest {
  // Optional. The name of the `Document` containing the `Chunk`s to delete.
  // The parent field in every `DeleteChunkRequest` must match this value.
  // Example: `corpora/my-corpus-123/documents/the-doc-abc`
  string parent = 1 [
    (google.api.field_behavior) = OPTIONAL,
    (google.api.resource_reference) = {
      child_type: "generativelanguage.googleapis.com/Chunk"
    }
  ];

  // Required. The request messages specifying the `Chunk`s to delete.
  repeated DeleteChunkRequest requests = 2
      [(google.api.field_behavior) = REQUIRED];
}

// Request for listing `Chunk`s.
message ListChunksRequest {
  // Required. The name of the `Document` containing `Chunk`s.
  // Example: `corpora/my-corpus-123/documents/the-doc-abc`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "generativelanguage.googleapis.com/Chunk"
    }
  ];

  // Optional. The maximum number of `Chunk`s to return (per page).
  // The service may return fewer `Chunk`s.
  //
  // If unspecified, at most 10 `Chunk`s will be returned.
  // The maximum size limit is 100 `Chunk`s per page.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A page token, received from a previous `ListChunks` call.
  //
  // Provide the `next_page_token` returned in the response as an argument to
  // the next request to retrieve the next page.
  //
  // When paginating, all other parameters provided to `ListChunks`
  // must match the call that provided the page token.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Response from `ListChunks` containing a paginated list of `Chunk`s.
// The `Chunk`s are sorted by ascending `chunk.create_time`.
message ListChunksResponse {
  // The returned `Chunk`s.
  repeated Chunk chunks = 1;

  // A token, which can be sent as `page_token` to retrieve the next page.
  // If this field is omitted, there are no more pages.
  string next_page_token = 2;
}
