// Copyright 2024 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated file. DO NOT EDIT.

// Package firebaseml provides access to the Firebase ML API.
//
// For product documentation, see: https://firebase.google.com
//
// # Library status
//
// These client libraries are officially supported by Google. However, this
// library is considered complete and is in maintenance mode. This means
// that we will address critical bugs and security issues but will not add
// any new features.
//
// When possible, we recommend using our newer
// [Cloud Client Libraries for Go](https://pkg.go.dev/cloud.google.com/go)
// that are still actively being worked and iterated on.
//
// # Creating a client
//
// Usage example:
//
//	import "google.golang.org/api/firebaseml/v2beta"
//	...
//	ctx := context.Background()
//	firebasemlService, err := firebaseml.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for
// authentication. For information on how to create and obtain Application
// Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// # Other authentication options
//
// To use an API key for authentication (note: some APIs do not support API
// keys), use [google.golang.org/api/option.WithAPIKey]:
//
//	firebasemlService, err := firebaseml.NewService(ctx, option.WithAPIKey("AIza..."))
//
// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth
// flow, use [google.golang.org/api/option.WithTokenSource]:
//
//	config := &oauth2.Config{...}
//	// ...
//	token, err := config.Exchange(ctx, ...)
//	firebasemlService, err := firebaseml.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See [google.golang.org/api/option.ClientOption] for details on options.
package firebaseml // import "google.golang.org/api/firebaseml/v2beta"

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	googleapi "google.golang.org/api/googleapi"
	internal "google.golang.org/api/internal"
	gensupport "google.golang.org/api/internal/gensupport"
	option "google.golang.org/api/option"
	internaloption "google.golang.org/api/option/internaloption"
	htransport "google.golang.org/api/transport/http"
)

// Always reference these packages, just in case the auto-generated code
// below doesn't.
var _ = bytes.NewBuffer
var _ = strconv.Itoa
var _ = fmt.Sprintf
var _ = json.NewDecoder
var _ = io.Copy
var _ = url.Parse
var _ = gensupport.MarshalJSON
var _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace
var _ = context.Canceled
var _ = internaloption.WithDefaultEndpoint
var _ = internal.Version

const apiId = "firebaseml:v2beta"
const apiName = "firebaseml"
const apiVersion = "v2beta"
const basePath = "https://firebaseml.googleapis.com/"
const basePathTemplate = "https://firebaseml.UNIVERSE_DOMAIN/"
const mtlsBasePath = "https://firebaseml.mtls.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// See, edit, configure, and delete your Google Cloud data and see the email
	// address for your Google Account.
	CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := internaloption.WithDefaultScopes(
		"https://www.googleapis.com/auth/cloud-platform",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	opts = append(opts, internaloption.WithDefaultEndpointTemplate(basePathTemplate))
	opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
	opts = append(opts, internaloption.EnableNewAuthLibrary())
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.Projects = NewProjectsService(s)
	return s, nil
}

type Service struct {
	client    *http.Client
	BasePath  string // API endpoint base URL
	UserAgent string // optional additional User-Agent fragment

	Projects *ProjectsService
}

func (s *Service) userAgent() string {
	if s.UserAgent == "" {
		return googleapi.UserAgent
	}
	return googleapi.UserAgent + " " + s.UserAgent
}

func NewProjectsService(s *Service) *ProjectsService {
	rs := &ProjectsService{s: s}
	rs.Locations = NewProjectsLocationsService(s)
	return rs
}

type ProjectsService struct {
	s *Service

	Locations *ProjectsLocationsService
}

func NewProjectsLocationsService(s *Service) *ProjectsLocationsService {
	rs := &ProjectsLocationsService{s: s}
	rs.Publishers = NewProjectsLocationsPublishersService(s)
	return rs
}

type ProjectsLocationsService struct {
	s *Service

	Publishers *ProjectsLocationsPublishersService
}

func NewProjectsLocationsPublishersService(s *Service) *ProjectsLocationsPublishersService {
	rs := &ProjectsLocationsPublishersService{s: s}
	rs.Models = NewProjectsLocationsPublishersModelsService(s)
	return rs
}

type ProjectsLocationsPublishersService struct {
	s *Service

	Models *ProjectsLocationsPublishersModelsService
}

func NewProjectsLocationsPublishersModelsService(s *Service) *ProjectsLocationsPublishersModelsService {
	rs := &ProjectsLocationsPublishersModelsService{s: s}
	return rs
}

type ProjectsLocationsPublishersModelsService struct {
	s *Service
}

// Date: Represents a whole or partial calendar date, such as a birthday. The
// time of day and time zone are either specified elsewhere or are
// insignificant. The date is relative to the Gregorian Calendar. This can
// represent one of the following: * A full date, with non-zero year, month,
// and day values. * A month and day, with a zero year (for example, an
// anniversary). * A year on its own, with a zero month and a zero day. * A
// year and month, with a zero day (for example, a credit card expiration
// date). Related types: * google.type.TimeOfDay * google.type.DateTime *
// google.protobuf.Timestamp
type Date struct {
	// Day: Day of a month. Must be from 1 to 31 and valid for the year and month,
	// or 0 to specify a year by itself or a year and month where the day isn't
	// significant.
	Day int64 `json:"day,omitempty"`
	// Month: Month of a year. Must be from 1 to 12, or 0 to specify a year without
	// a month and day.
	Month int64 `json:"month,omitempty"`
	// Year: Year of the date. Must be from 1 to 9999, or 0 to specify a date
	// without a year.
	Year int64 `json:"year,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Day") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Day") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *Date) MarshalJSON() ([]byte, error) {
	type NoMethod Date
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1Blob: Content blob. It's preferred to send as
// text directly rather than raw bytes.
type GoogleCloudAiplatformV1beta1Blob struct {
	// Data: Required. Raw bytes.
	Data string `json:"data,omitempty"`
	// MimeType: Required. The IANA standard MIME type of the source data.
	MimeType string `json:"mimeType,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Data") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Data") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1Blob) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1Blob
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1Candidate: A response candidate generated from
// the model.
type GoogleCloudAiplatformV1beta1Candidate struct {
	// CitationMetadata: Output only. Source attribution of the generated content.
	CitationMetadata *GoogleCloudAiplatformV1beta1CitationMetadata `json:"citationMetadata,omitempty"`
	// Content: Output only. Content parts of the candidate.
	Content *GoogleCloudAiplatformV1beta1Content `json:"content,omitempty"`
	// FinishMessage: Output only. Describes the reason the mode stopped generating
	// tokens in more detail. This is only filled when `finish_reason` is set.
	FinishMessage string `json:"finishMessage,omitempty"`
	// FinishReason: Output only. The reason why the model stopped generating
	// tokens. If empty, the model has not stopped generating the tokens.
	//
	// Possible values:
	//   "FINISH_REASON_UNSPECIFIED" - The finish reason is unspecified.
	//   "STOP" - Natural stop point of the model or provided stop sequence.
	//   "MAX_TOKENS" - The maximum number of tokens as specified in the request
	// was reached.
	//   "SAFETY" - The token generation was stopped as the response was flagged
	// for safety reasons. NOTE: When streaming the Candidate.content will be empty
	// if content filters blocked the output.
	//   "RECITATION" - The token generation was stopped as the response was
	// flagged for unauthorized citations.
	//   "OTHER" - All other reasons that stopped the token generation
	//   "BLOCKLIST" - The token generation was stopped as the response was flagged
	// for the terms which are included from the terminology blocklist.
	//   "PROHIBITED_CONTENT" - The token generation was stopped as the response
	// was flagged for the prohibited contents.
	//   "SPII" - The token generation was stopped as the response was flagged for
	// Sensitive Personally Identifiable Information (SPII) contents.
	//   "MALFORMED_FUNCTION_CALL" - The function call generated by the model is
	// invalid.
	FinishReason string `json:"finishReason,omitempty"`
	// GroundingMetadata: Output only. Metadata specifies sources used to ground
	// generated content.
	GroundingMetadata *GoogleCloudAiplatformV1beta1GroundingMetadata `json:"groundingMetadata,omitempty"`
	// Index: Output only. Index of the candidate.
	Index int64 `json:"index,omitempty"`
	// SafetyRatings: Output only. List of ratings for the safety of a response
	// candidate. There is at most one rating per category.
	SafetyRatings []*GoogleCloudAiplatformV1beta1SafetyRating `json:"safetyRatings,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CitationMetadata") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CitationMetadata") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1Candidate) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1Candidate
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1Citation: Source attributions for content.
type GoogleCloudAiplatformV1beta1Citation struct {
	// EndIndex: Output only. End index into the content.
	EndIndex int64 `json:"endIndex,omitempty"`
	// License: Output only. License of the attribution.
	License string `json:"license,omitempty"`
	// PublicationDate: Output only. Publication date of the attribution.
	PublicationDate *Date `json:"publicationDate,omitempty"`
	// StartIndex: Output only. Start index into the content.
	StartIndex int64 `json:"startIndex,omitempty"`
	// Title: Output only. Title of the attribution.
	Title string `json:"title,omitempty"`
	// Uri: Output only. Url reference of the attribution.
	Uri string `json:"uri,omitempty"`
	// ForceSendFields is a list of field names (e.g. "EndIndex") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "EndIndex") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1Citation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1Citation
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1CitationMetadata: A collection of source
// attributions for a piece of content.
type GoogleCloudAiplatformV1beta1CitationMetadata struct {
	// Citations: Output only. List of citations.
	Citations []*GoogleCloudAiplatformV1beta1Citation `json:"citations,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Citations") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Citations") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1CitationMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1CitationMetadata
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1Content: The base structured datatype containing
// multi-part content of a message. A `Content` includes a `role` field
// designating the producer of the `Content` and a `parts` field containing
// multi-part data that contains the content of the message turn.
type GoogleCloudAiplatformV1beta1Content struct {
	// Parts: Required. Ordered `Parts` that constitute a single message. Parts may
	// have different IANA MIME types.
	Parts []*GoogleCloudAiplatformV1beta1Part `json:"parts,omitempty"`
	// Role: Optional. The producer of the content. Must be either 'user' or
	// 'model'. Useful to set for multi-turn conversations, otherwise can be left
	// blank or unset.
	Role string `json:"role,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Parts") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Parts") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1Content) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1Content
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1CountTokensRequest: Request message for
// PredictionService.CountTokens.
type GoogleCloudAiplatformV1beta1CountTokensRequest struct {
	// Contents: Required. Input content.
	Contents []*GoogleCloudAiplatformV1beta1Content `json:"contents,omitempty"`
	// Instances: Required. The instances that are the input to token counting
	// call. Schema is identical to the prediction schema of the underlying model.
	Instances []interface{} `json:"instances,omitempty"`
	// Model: Required. The name of the publisher model requested to serve the
	// prediction. Format:
	// `projects/{project}/locations/{location}/publishers/*/models/*`
	Model string `json:"model,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Contents") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Contents") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1CountTokensRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1CountTokensRequest
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1CountTokensResponse: Response message for
// PredictionService.CountTokens.
type GoogleCloudAiplatformV1beta1CountTokensResponse struct {
	// TotalBillableCharacters: The total number of billable characters counted
	// across all instances from the request.
	TotalBillableCharacters int64 `json:"totalBillableCharacters,omitempty"`
	// TotalTokens: The total number of tokens counted across all instances from
	// the request.
	TotalTokens int64 `json:"totalTokens,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "TotalBillableCharacters") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "TotalBillableCharacters") to
	// include in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1CountTokensResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1CountTokensResponse
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1FileData: URI based data.
type GoogleCloudAiplatformV1beta1FileData struct {
	// FileUri: Required. URI.
	FileUri string `json:"fileUri,omitempty"`
	// MimeType: Required. The IANA standard MIME type of the source data.
	MimeType string `json:"mimeType,omitempty"`
	// ForceSendFields is a list of field names (e.g. "FileUri") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "FileUri") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1FileData) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1FileData
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1FunctionCall: A predicted [FunctionCall]
// returned from the model that contains a string representing the
// [FunctionDeclaration.name] and a structured JSON object containing the
// parameters and their values.
type GoogleCloudAiplatformV1beta1FunctionCall struct {
	// Args: Optional. Required. The function parameters and values in JSON object
	// format. See [FunctionDeclaration.parameters] for parameter details.
	Args googleapi.RawMessage `json:"args,omitempty"`
	// Name: Required. The name of the function to call. Matches
	// [FunctionDeclaration.name].
	Name string `json:"name,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Args") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Args") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1FunctionCall) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1FunctionCall
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1FunctionCallingConfig: Function calling config.
type GoogleCloudAiplatformV1beta1FunctionCallingConfig struct {
	// AllowedFunctionNames: Optional. Function names to call. Only set when the
	// Mode is ANY. Function names should match [FunctionDeclaration.name]. With
	// mode set to ANY, model will predict a function call from the set of function
	// names provided.
	AllowedFunctionNames []string `json:"allowedFunctionNames,omitempty"`
	// Mode: Optional. Function calling mode.
	//
	// Possible values:
	//   "MODE_UNSPECIFIED" - Unspecified function calling mode. This value should
	// not be used.
	//   "AUTO" - Default model behavior, model decides to predict either a
	// function call or a natural language repspose.
	//   "ANY" - Model is constrained to always predicting a function call only. If
	// "allowed_function_names" are set, the predicted function call will be
	// limited to any one of "allowed_function_names", else the predicted function
	// call will be any one of the provided "function_declarations".
	//   "NONE" - Model will not predict any function call. Model behavior is same
	// as when not passing any function declarations.
	Mode string `json:"mode,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AllowedFunctionNames") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AllowedFunctionNames") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1FunctionCallingConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1FunctionCallingConfig
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1FunctionDeclaration: Structured representation
// of a function declaration as defined by the OpenAPI 3.0 specification
// (https://spec.openapis.org/oas/v3.0.3). Included in this declaration are the
// function name and parameters. This FunctionDeclaration is a representation
// of a block of code that can be used as a `Tool` by the model and executed by
// the client.
type GoogleCloudAiplatformV1beta1FunctionDeclaration struct {
	// Description: Optional. Description and purpose of the function. Model uses
	// it to decide how and whether to call the function.
	Description string `json:"description,omitempty"`
	// Name: Required. The name of the function to call. Must start with a letter
	// or an underscore. Must be a-z, A-Z, 0-9, or contain underscores, dots and
	// dashes, with a maximum length of 64.
	Name string `json:"name,omitempty"`
	// Parameters: Optional. Describes the parameters to this function in JSON
	// Schema Object format. Reflects the Open API 3.03 Parameter Object. string
	// Key: the name of the parameter. Parameter names are case sensitive. Schema
	// Value: the Schema defining the type used for the parameter. For function
	// with no parameters, this can be left unset. Parameter names must start with
	// a letter or an underscore and must only contain chars a-z, A-Z, 0-9, or
	// underscores with a maximum length of 64. Example with 1 required and 1
	// optional parameter: type: OBJECT properties: param1: type: STRING param2:
	// type: INTEGER required: - param1
	Parameters *GoogleCloudAiplatformV1beta1Schema `json:"parameters,omitempty"`
	// Response: Optional. Describes the output from this function in JSON Schema
	// format. Reflects the Open API 3.03 Response Object. The Schema defines the
	// type used for the response value of the function.
	Response *GoogleCloudAiplatformV1beta1Schema `json:"response,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Description") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1FunctionDeclaration) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1FunctionDeclaration
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1FunctionResponse: The result output from a
// [FunctionCall] that contains a string representing the
// [FunctionDeclaration.name] and a structured JSON object containing any
// output from the function is used as context to the model. This should
// contain the result of a [FunctionCall] made based on model prediction.
type GoogleCloudAiplatformV1beta1FunctionResponse struct {
	// Name: Required. The name of the function to call. Matches
	// [FunctionDeclaration.name] and [FunctionCall.name].
	Name string `json:"name,omitempty"`
	// Response: Required. The function response in JSON object format.
	Response googleapi.RawMessage `json:"response,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Name") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Name") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1FunctionResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1FunctionResponse
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1GenerateContentRequest: Request message for
// [PredictionService.GenerateContent].
type GoogleCloudAiplatformV1beta1GenerateContentRequest struct {
	// CachedContent: Optional. The name of the cached content used as context to
	// serve the prediction. Note: only used in explicit caching, where users can
	// have control over caching (e.g. what content to cache) and enjoy guaranteed
	// cost savings. Format:
	// `projects/{project}/locations/{location}/cachedContents/{cachedContent}`
	CachedContent string `json:"cachedContent,omitempty"`
	// Contents: Required. The content of the current conversation with the model.
	// For single-turn queries, this is a single instance. For multi-turn queries,
	// this is a repeated field that contains conversation history + latest
	// request.
	Contents []*GoogleCloudAiplatformV1beta1Content `json:"contents,omitempty"`
	// GenerationConfig: Optional. Generation config.
	GenerationConfig *GoogleCloudAiplatformV1beta1GenerationConfig `json:"generationConfig,omitempty"`
	// SafetySettings: Optional. Per request settings for blocking unsafe content.
	// Enforced on GenerateContentResponse.candidates.
	SafetySettings []*GoogleCloudAiplatformV1beta1SafetySetting `json:"safetySettings,omitempty"`
	// SystemInstruction: Optional. The user provided system instructions for the
	// model. Note: only text should be used in parts and content in each part will
	// be in a separate paragraph.
	SystemInstruction *GoogleCloudAiplatformV1beta1Content `json:"systemInstruction,omitempty"`
	// ToolConfig: Optional. Tool config. This config is shared for all tools
	// provided in the request.
	ToolConfig *GoogleCloudAiplatformV1beta1ToolConfig `json:"toolConfig,omitempty"`
	// Tools: Optional. A list of `Tools` the model may use to generate the next
	// response. A `Tool` is a piece of code that enables the system to interact
	// with external systems to perform an action, or set of actions, outside of
	// knowledge and scope of the model.
	Tools []*GoogleCloudAiplatformV1beta1Tool `json:"tools,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CachedContent") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CachedContent") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1GenerateContentRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1GenerateContentRequest
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1GenerateContentResponse: Response message for
// [PredictionService.GenerateContent].
type GoogleCloudAiplatformV1beta1GenerateContentResponse struct {
	// Candidates: Output only. Generated candidates.
	Candidates []*GoogleCloudAiplatformV1beta1Candidate `json:"candidates,omitempty"`
	// PromptFeedback: Output only. Content filter results for a prompt sent in the
	// request. Note: Sent only in the first stream chunk. Only happens when no
	// candidates were generated due to content violations.
	PromptFeedback *GoogleCloudAiplatformV1beta1GenerateContentResponsePromptFeedback `json:"promptFeedback,omitempty"`
	// UsageMetadata: Usage metadata about the response(s).
	UsageMetadata *GoogleCloudAiplatformV1beta1GenerateContentResponseUsageMetadata `json:"usageMetadata,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "Candidates") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Candidates") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1GenerateContentResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1GenerateContentResponse
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1GenerateContentResponsePromptFeedback: Content
// filter results for a prompt sent in the request.
type GoogleCloudAiplatformV1beta1GenerateContentResponsePromptFeedback struct {
	// BlockReason: Output only. Blocked reason.
	//
	// Possible values:
	//   "BLOCKED_REASON_UNSPECIFIED" - Unspecified blocked reason.
	//   "SAFETY" - Candidates blocked due to safety.
	//   "OTHER" - Candidates blocked due to other reason.
	//   "BLOCKLIST" - Candidates blocked due to the terms which are included from
	// the terminology blocklist.
	//   "PROHIBITED_CONTENT" - Candidates blocked due to prohibited content.
	BlockReason string `json:"blockReason,omitempty"`
	// BlockReasonMessage: Output only. A readable block reason message.
	BlockReasonMessage string `json:"blockReasonMessage,omitempty"`
	// SafetyRatings: Output only. Safety ratings.
	SafetyRatings []*GoogleCloudAiplatformV1beta1SafetyRating `json:"safetyRatings,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BlockReason") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "BlockReason") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1GenerateContentResponsePromptFeedback) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1GenerateContentResponsePromptFeedback
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1GenerateContentResponseUsageMetadata: Usage
// metadata about response(s).
type GoogleCloudAiplatformV1beta1GenerateContentResponseUsageMetadata struct {
	// CandidatesTokenCount: Number of tokens in the response(s).
	CandidatesTokenCount int64 `json:"candidatesTokenCount,omitempty"`
	// PromptTokenCount: Number of tokens in the request.
	PromptTokenCount int64 `json:"promptTokenCount,omitempty"`
	TotalTokenCount  int64 `json:"totalTokenCount,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CandidatesTokenCount") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CandidatesTokenCount") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1GenerateContentResponseUsageMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1GenerateContentResponseUsageMetadata
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1GenerationConfig: Generation config.
type GoogleCloudAiplatformV1beta1GenerationConfig struct {
	// CandidateCount: Optional. Number of candidates to generate.
	CandidateCount int64 `json:"candidateCount,omitempty"`
	// FrequencyPenalty: Optional. Frequency penalties.
	FrequencyPenalty float64 `json:"frequencyPenalty,omitempty"`
	// MaxOutputTokens: Optional. The maximum number of output tokens to generate
	// per message.
	MaxOutputTokens int64 `json:"maxOutputTokens,omitempty"`
	// PresencePenalty: Optional. Positive penalties.
	PresencePenalty float64 `json:"presencePenalty,omitempty"`
	// ResponseMimeType: Optional. Output response mimetype of the generated
	// candidate text. Supported mimetype: - `text/plain`: (default) Text output. -
	// `application/json`: JSON response in the candidates. The model needs to be
	// prompted to output the appropriate response type, otherwise the behavior is
	// undefined. This is a preview feature.
	ResponseMimeType string `json:"responseMimeType,omitempty"`
	// ResponseSchema: Optional. The `Schema` object allows the definition of input
	// and output data types. These types can be objects, but also primitives and
	// arrays. Represents a select subset of an OpenAPI 3.0 schema object
	// (https://spec.openapis.org/oas/v3.0.3#schema). If set, a compatible
	// response_mime_type must also be set. Compatible mimetypes:
	// `application/json`: Schema for JSON response.
	ResponseSchema *GoogleCloudAiplatformV1beta1Schema `json:"responseSchema,omitempty"`
	// StopSequences: Optional. Stop sequences.
	StopSequences []string `json:"stopSequences,omitempty"`
	// Temperature: Optional. Controls the randomness of predictions.
	Temperature float64 `json:"temperature,omitempty"`
	// TopK: Optional. If specified, top-k sampling will be used.
	TopK float64 `json:"topK,omitempty"`
	// TopP: Optional. If specified, nucleus sampling will be used.
	TopP float64 `json:"topP,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CandidateCount") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CandidateCount") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1GenerationConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1GenerationConfig
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudAiplatformV1beta1GenerationConfig) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudAiplatformV1beta1GenerationConfig
	var s1 struct {
		FrequencyPenalty gensupport.JSONFloat64 `json:"frequencyPenalty"`
		PresencePenalty  gensupport.JSONFloat64 `json:"presencePenalty"`
		Temperature      gensupport.JSONFloat64 `json:"temperature"`
		TopK             gensupport.JSONFloat64 `json:"topK"`
		TopP             gensupport.JSONFloat64 `json:"topP"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.FrequencyPenalty = float64(s1.FrequencyPenalty)
	s.PresencePenalty = float64(s1.PresencePenalty)
	s.Temperature = float64(s1.Temperature)
	s.TopK = float64(s1.TopK)
	s.TopP = float64(s1.TopP)
	return nil
}

// GoogleCloudAiplatformV1beta1GoogleSearchRetrieval: Tool to retrieve public
// web data for grounding, powered by Google.
type GoogleCloudAiplatformV1beta1GoogleSearchRetrieval struct {
}

// GoogleCloudAiplatformV1beta1GroundingAttribution: Grounding attribution.
type GoogleCloudAiplatformV1beta1GroundingAttribution struct {
	// ConfidenceScore: Optional. Output only. Confidence score of the attribution.
	// Ranges from 0 to 1. 1 is the most confident.
	ConfidenceScore float64 `json:"confidenceScore,omitempty"`
	// RetrievedContext: Optional. Attribution from context retrieved by the
	// retrieval tools.
	RetrievedContext *GoogleCloudAiplatformV1beta1GroundingAttributionRetrievedContext `json:"retrievedContext,omitempty"`
	// Segment: Output only. Segment of the content this attribution belongs to.
	Segment *GoogleCloudAiplatformV1beta1Segment `json:"segment,omitempty"`
	// Web: Optional. Attribution from the web.
	Web *GoogleCloudAiplatformV1beta1GroundingAttributionWeb `json:"web,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ConfidenceScore") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ConfidenceScore") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1GroundingAttribution) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1GroundingAttribution
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudAiplatformV1beta1GroundingAttribution) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudAiplatformV1beta1GroundingAttribution
	var s1 struct {
		ConfidenceScore gensupport.JSONFloat64 `json:"confidenceScore"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.ConfidenceScore = float64(s1.ConfidenceScore)
	return nil
}

// GoogleCloudAiplatformV1beta1GroundingAttributionRetrievedContext:
// Attribution from context retrieved by the retrieval tools.
type GoogleCloudAiplatformV1beta1GroundingAttributionRetrievedContext struct {
	// Title: Output only. Title of the attribution.
	Title string `json:"title,omitempty"`
	// Uri: Output only. URI reference of the attribution.
	Uri string `json:"uri,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Title") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Title") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1GroundingAttributionRetrievedContext) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1GroundingAttributionRetrievedContext
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1GroundingAttributionWeb: Attribution from the
// web.
type GoogleCloudAiplatformV1beta1GroundingAttributionWeb struct {
	// Title: Output only. Title of the attribution.
	Title string `json:"title,omitempty"`
	// Uri: Output only. URI reference of the attribution.
	Uri string `json:"uri,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Title") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Title") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1GroundingAttributionWeb) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1GroundingAttributionWeb
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1GroundingChunk: Grounding chunk.
type GoogleCloudAiplatformV1beta1GroundingChunk struct {
	// RetrievedContext: Grounding chunk from context retrieved by the retrieval
	// tools.
	RetrievedContext *GoogleCloudAiplatformV1beta1GroundingChunkRetrievedContext `json:"retrievedContext,omitempty"`
	// Web: Grounding chunk from the web.
	Web *GoogleCloudAiplatformV1beta1GroundingChunkWeb `json:"web,omitempty"`
	// ForceSendFields is a list of field names (e.g. "RetrievedContext") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "RetrievedContext") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1GroundingChunk) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1GroundingChunk
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1GroundingChunkRetrievedContext: Chunk from
// context retrieved by the retrieval tools.
type GoogleCloudAiplatformV1beta1GroundingChunkRetrievedContext struct {
	// Title: Title of the attribution.
	Title string `json:"title,omitempty"`
	// Uri: URI reference of the attribution.
	Uri string `json:"uri,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Title") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Title") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1GroundingChunkRetrievedContext) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1GroundingChunkRetrievedContext
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1GroundingChunkWeb: Chunk from the web.
type GoogleCloudAiplatformV1beta1GroundingChunkWeb struct {
	// Title: Title of the chunk.
	Title string `json:"title,omitempty"`
	// Uri: URI reference of the chunk.
	Uri string `json:"uri,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Title") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Title") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1GroundingChunkWeb) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1GroundingChunkWeb
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1GroundingMetadata: Metadata returned to client
// when grounding is enabled.
type GoogleCloudAiplatformV1beta1GroundingMetadata struct {
	// GroundingAttributions: Optional. List of grounding attributions.
	GroundingAttributions []*GoogleCloudAiplatformV1beta1GroundingAttribution `json:"groundingAttributions,omitempty"`
	// GroundingChunks: List of supporting references retrieved from specified
	// grounding source.
	GroundingChunks []*GoogleCloudAiplatformV1beta1GroundingChunk `json:"groundingChunks,omitempty"`
	// GroundingSupports: Optional. List of grounding support.
	GroundingSupports []*GoogleCloudAiplatformV1beta1GroundingSupport `json:"groundingSupports,omitempty"`
	// RetrievalQueries: Optional. Queries executed by the retrieval tools.
	RetrievalQueries []string `json:"retrievalQueries,omitempty"`
	// SearchEntryPoint: Optional. Google search entry for the following-up web
	// searches.
	SearchEntryPoint *GoogleCloudAiplatformV1beta1SearchEntryPoint `json:"searchEntryPoint,omitempty"`
	// WebSearchQueries: Optional. Web search queries for the following-up web
	// search.
	WebSearchQueries []string `json:"webSearchQueries,omitempty"`
	// ForceSendFields is a list of field names (e.g. "GroundingAttributions") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "GroundingAttributions") to
	// include in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1GroundingMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1GroundingMetadata
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1GroundingSupport: Grounding support.
type GoogleCloudAiplatformV1beta1GroundingSupport struct {
	// ConfidenceScores: Confidence score of the support references. Ranges from 0
	// to 1. 1 is the most confident. This list must have the same size as the
	// grounding_chunk_indices.
	ConfidenceScores []float64 `json:"confidenceScores,omitempty"`
	// GroundingChunkIndices: A list of indices (into 'grounding_chunk') specifying
	// the citations associated with the claim. For instance [1,3,4] means that
	// grounding_chunk[1], grounding_chunk[3], grounding_chunk[4] are the retrieved
	// content attributed to the claim.
	GroundingChunkIndices []int64 `json:"groundingChunkIndices,omitempty"`
	// Segment: Segment of the content this support belongs to.
	Segment *GoogleCloudAiplatformV1beta1Segment `json:"segment,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ConfidenceScores") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ConfidenceScores") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1GroundingSupport) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1GroundingSupport
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudAiplatformV1beta1GroundingSupport) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudAiplatformV1beta1GroundingSupport
	var s1 struct {
		ConfidenceScores []gensupport.JSONFloat64 `json:"confidenceScores"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.ConfidenceScores = make([]float64, len(s1.ConfidenceScores))
	for i := range s1.ConfidenceScores {
		s.ConfidenceScores[i] = float64(s1.ConfidenceScores[i])
	}
	return nil
}

// GoogleCloudAiplatformV1beta1Part: A datatype containing media that is part
// of a multi-part `Content` message. A `Part` consists of data which has an
// associated datatype. A `Part` can only contain one of the accepted types in
// `Part.data`. A `Part` must have a fixed IANA MIME type identifying the type
// and subtype of the media if `inline_data` or `file_data` field is filled
// with raw bytes.
type GoogleCloudAiplatformV1beta1Part struct {
	// FileData: Optional. URI based data.
	FileData *GoogleCloudAiplatformV1beta1FileData `json:"fileData,omitempty"`
	// FunctionCall: Optional. A predicted [FunctionCall] returned from the model
	// that contains a string representing the [FunctionDeclaration.name] with the
	// parameters and their values.
	FunctionCall *GoogleCloudAiplatformV1beta1FunctionCall `json:"functionCall,omitempty"`
	// FunctionResponse: Optional. The result output of a [FunctionCall] that
	// contains a string representing the [FunctionDeclaration.name] and a
	// structured JSON object containing any output from the function call. It is
	// used as context to the model.
	FunctionResponse *GoogleCloudAiplatformV1beta1FunctionResponse `json:"functionResponse,omitempty"`
	// InlineData: Optional. Inlined bytes data.
	InlineData *GoogleCloudAiplatformV1beta1Blob `json:"inlineData,omitempty"`
	// Text: Optional. Text part (can be code).
	Text string `json:"text,omitempty"`
	// VideoMetadata: Optional. Video metadata. The metadata should only be
	// specified while the video data is presented in inline_data or file_data.
	VideoMetadata *GoogleCloudAiplatformV1beta1VideoMetadata `json:"videoMetadata,omitempty"`
	// ForceSendFields is a list of field names (e.g. "FileData") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "FileData") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1Part) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1Part
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1Retrieval: Defines a retrieval tool that model
// can call to access external knowledge.
type GoogleCloudAiplatformV1beta1Retrieval struct {
	// DisableAttribution: Optional. Disable using the result from this tool in
	// detecting grounding attribution. This does not affect how the result is
	// given to the model for generation.
	DisableAttribution bool `json:"disableAttribution,omitempty"`
	// VertexAiSearch: Set to use data source powered by Vertex AI Search.
	VertexAiSearch *GoogleCloudAiplatformV1beta1VertexAISearch `json:"vertexAiSearch,omitempty"`
	// VertexRagStore: Set to use data source powered by Vertex RAG store. User
	// data is uploaded via the VertexRagDataService.
	VertexRagStore *GoogleCloudAiplatformV1beta1VertexRagStore `json:"vertexRagStore,omitempty"`
	// ForceSendFields is a list of field names (e.g. "DisableAttribution") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "DisableAttribution") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1Retrieval) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1Retrieval
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1SafetyRating: Safety rating corresponding to the
// generated content.
type GoogleCloudAiplatformV1beta1SafetyRating struct {
	// Blocked: Output only. Indicates whether the content was filtered out because
	// of this rating.
	Blocked bool `json:"blocked,omitempty"`
	// Category: Output only. Harm category.
	//
	// Possible values:
	//   "HARM_CATEGORY_UNSPECIFIED" - The harm category is unspecified.
	//   "HARM_CATEGORY_HATE_SPEECH" - The harm category is hate speech.
	//   "HARM_CATEGORY_DANGEROUS_CONTENT" - The harm category is dangerous
	// content.
	//   "HARM_CATEGORY_HARASSMENT" - The harm category is harassment.
	//   "HARM_CATEGORY_SEXUALLY_EXPLICIT" - The harm category is sexually explicit
	// content.
	Category string `json:"category,omitempty"`
	// Probability: Output only. Harm probability levels in the content.
	//
	// Possible values:
	//   "HARM_PROBABILITY_UNSPECIFIED" - Harm probability unspecified.
	//   "NEGLIGIBLE" - Negligible level of harm.
	//   "LOW" - Low level of harm.
	//   "MEDIUM" - Medium level of harm.
	//   "HIGH" - High level of harm.
	Probability string `json:"probability,omitempty"`
	// ProbabilityScore: Output only. Harm probability score.
	ProbabilityScore float64 `json:"probabilityScore,omitempty"`
	// Severity: Output only. Harm severity levels in the content.
	//
	// Possible values:
	//   "HARM_SEVERITY_UNSPECIFIED" - Harm severity unspecified.
	//   "HARM_SEVERITY_NEGLIGIBLE" - Negligible level of harm severity.
	//   "HARM_SEVERITY_LOW" - Low level of harm severity.
	//   "HARM_SEVERITY_MEDIUM" - Medium level of harm severity.
	//   "HARM_SEVERITY_HIGH" - High level of harm severity.
	Severity string `json:"severity,omitempty"`
	// SeverityScore: Output only. Harm severity score.
	SeverityScore float64 `json:"severityScore,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Blocked") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Blocked") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1SafetyRating) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1SafetyRating
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudAiplatformV1beta1SafetyRating) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudAiplatformV1beta1SafetyRating
	var s1 struct {
		ProbabilityScore gensupport.JSONFloat64 `json:"probabilityScore"`
		SeverityScore    gensupport.JSONFloat64 `json:"severityScore"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.ProbabilityScore = float64(s1.ProbabilityScore)
	s.SeverityScore = float64(s1.SeverityScore)
	return nil
}

// GoogleCloudAiplatformV1beta1SafetySetting: Safety settings.
type GoogleCloudAiplatformV1beta1SafetySetting struct {
	// Category: Required. Harm category.
	//
	// Possible values:
	//   "HARM_CATEGORY_UNSPECIFIED" - The harm category is unspecified.
	//   "HARM_CATEGORY_HATE_SPEECH" - The harm category is hate speech.
	//   "HARM_CATEGORY_DANGEROUS_CONTENT" - The harm category is dangerous
	// content.
	//   "HARM_CATEGORY_HARASSMENT" - The harm category is harassment.
	//   "HARM_CATEGORY_SEXUALLY_EXPLICIT" - The harm category is sexually explicit
	// content.
	Category string `json:"category,omitempty"`
	// Method: Optional. Specify if the threshold is used for probability or
	// severity score. If not specified, the threshold is used for probability
	// score.
	//
	// Possible values:
	//   "HARM_BLOCK_METHOD_UNSPECIFIED" - The harm block method is unspecified.
	//   "SEVERITY" - The harm block method uses both probability and severity
	// scores.
	//   "PROBABILITY" - The harm block method uses the probability score.
	Method string `json:"method,omitempty"`
	// Threshold: Required. The harm block threshold.
	//
	// Possible values:
	//   "HARM_BLOCK_THRESHOLD_UNSPECIFIED" - Unspecified harm block threshold.
	//   "BLOCK_LOW_AND_ABOVE" - Block low threshold and above (i.e. block more).
	//   "BLOCK_MEDIUM_AND_ABOVE" - Block medium threshold and above.
	//   "BLOCK_ONLY_HIGH" - Block only high threshold (i.e. block less).
	//   "BLOCK_NONE" - Block none.
	Threshold string `json:"threshold,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Category") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Category") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1SafetySetting) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1SafetySetting
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1Schema: Schema is used to define the format of
// input/output data. Represents a select subset of an OpenAPI 3.0 schema
// object (https://spec.openapis.org/oas/v3.0.3#schema). More fields may be
// added in the future as needed.
type GoogleCloudAiplatformV1beta1Schema struct {
	// Default: Optional. Default value of the data.
	Default interface{} `json:"default,omitempty"`
	// Description: Optional. The description of the data.
	Description string `json:"description,omitempty"`
	// Enum: Optional. Possible values of the element of Type.STRING with enum
	// format. For example we can define an Enum Direction as : {type:STRING,
	// format:enum, enum:["EAST", NORTH", "SOUTH", "WEST"]}
	Enum []string `json:"enum,omitempty"`
	// Example: Optional. Example of the object. Will only populated when the
	// object is the root.
	Example interface{} `json:"example,omitempty"`
	// Format: Optional. The format of the data. Supported formats: for NUMBER
	// type: "float", "double" for INTEGER type: "int32", "int64" for STRING type:
	// "email", "byte", etc
	Format string `json:"format,omitempty"`
	// Items: Optional. SCHEMA FIELDS FOR TYPE ARRAY Schema of the elements of
	// Type.ARRAY.
	Items *GoogleCloudAiplatformV1beta1Schema `json:"items,omitempty"`
	// MaxItems: Optional. Maximum number of the elements for Type.ARRAY.
	MaxItems int64 `json:"maxItems,omitempty,string"`
	// MaxLength: Optional. Maximum length of the Type.STRING
	MaxLength int64 `json:"maxLength,omitempty,string"`
	// MaxProperties: Optional. Maximum number of the properties for Type.OBJECT.
	MaxProperties int64 `json:"maxProperties,omitempty,string"`
	// Maximum: Optional. Maximum value of the Type.INTEGER and Type.NUMBER
	Maximum float64 `json:"maximum,omitempty"`
	// MinItems: Optional. Minimum number of the elements for Type.ARRAY.
	MinItems int64 `json:"minItems,omitempty,string"`
	// MinLength: Optional. SCHEMA FIELDS FOR TYPE STRING Minimum length of the
	// Type.STRING
	MinLength int64 `json:"minLength,omitempty,string"`
	// MinProperties: Optional. Minimum number of the properties for Type.OBJECT.
	MinProperties int64 `json:"minProperties,omitempty,string"`
	// Minimum: Optional. SCHEMA FIELDS FOR TYPE INTEGER and NUMBER Minimum value
	// of the Type.INTEGER and Type.NUMBER
	Minimum float64 `json:"minimum,omitempty"`
	// Nullable: Optional. Indicates if the value may be null.
	Nullable bool `json:"nullable,omitempty"`
	// Pattern: Optional. Pattern of the Type.STRING to restrict a string to a
	// regular expression.
	Pattern string `json:"pattern,omitempty"`
	// Properties: Optional. SCHEMA FIELDS FOR TYPE OBJECT Properties of
	// Type.OBJECT.
	Properties map[string]GoogleCloudAiplatformV1beta1Schema `json:"properties,omitempty"`
	// Required: Optional. Required properties of Type.OBJECT.
	Required []string `json:"required,omitempty"`
	// Title: Optional. The title of the Schema.
	Title string `json:"title,omitempty"`
	// Type: Optional. The type of the data.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - Not specified, should not be used.
	//   "STRING" - OpenAPI string type
	//   "NUMBER" - OpenAPI number type
	//   "INTEGER" - OpenAPI integer type
	//   "BOOLEAN" - OpenAPI boolean type
	//   "ARRAY" - OpenAPI array type
	//   "OBJECT" - OpenAPI object type
	Type string `json:"type,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Default") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Default") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1Schema) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1Schema
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudAiplatformV1beta1Schema) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudAiplatformV1beta1Schema
	var s1 struct {
		Maximum gensupport.JSONFloat64 `json:"maximum"`
		Minimum gensupport.JSONFloat64 `json:"minimum"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Maximum = float64(s1.Maximum)
	s.Minimum = float64(s1.Minimum)
	return nil
}

// GoogleCloudAiplatformV1beta1SearchEntryPoint: Google search entry point.
type GoogleCloudAiplatformV1beta1SearchEntryPoint struct {
	// RenderedContent: Optional. Web content snippet that can be embedded in a web
	// page or an app webview.
	RenderedContent string `json:"renderedContent,omitempty"`
	// SdkBlob: Optional. Base64 encoded JSON representing array of tuple.
	SdkBlob string `json:"sdkBlob,omitempty"`
	// ForceSendFields is a list of field names (e.g. "RenderedContent") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "RenderedContent") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1SearchEntryPoint) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1SearchEntryPoint
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1Segment: Segment of the content.
type GoogleCloudAiplatformV1beta1Segment struct {
	// EndIndex: Output only. End index in the given Part, measured in bytes.
	// Offset from the start of the Part, exclusive, starting at zero.
	EndIndex int64 `json:"endIndex,omitempty"`
	// PartIndex: Output only. The index of a Part object within its parent Content
	// object.
	PartIndex int64 `json:"partIndex,omitempty"`
	// StartIndex: Output only. Start index in the given Part, measured in bytes.
	// Offset from the start of the Part, inclusive, starting at zero.
	StartIndex int64 `json:"startIndex,omitempty"`
	// Text: Output only. The text corresponding to the segment from the response.
	Text string `json:"text,omitempty"`
	// ForceSendFields is a list of field names (e.g. "EndIndex") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "EndIndex") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1Segment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1Segment
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1Tool: Tool details that the model may use to
// generate response. A `Tool` is a piece of code that enables the system to
// interact with external systems to perform an action, or set of actions,
// outside of knowledge and scope of the model. A Tool object should contain
// exactly one type of Tool (e.g FunctionDeclaration, Retrieval or
// GoogleSearchRetrieval).
type GoogleCloudAiplatformV1beta1Tool struct {
	// FunctionDeclarations: Optional. Function tool type. One or more function
	// declarations to be passed to the model along with the current user query.
	// Model may decide to call a subset of these functions by populating
	// FunctionCall in the response. User should provide a FunctionResponse for
	// each function call in the next turn. Based on the function responses, Model
	// will generate the final response back to the user. Maximum 64 function
	// declarations can be provided.
	FunctionDeclarations []*GoogleCloudAiplatformV1beta1FunctionDeclaration `json:"functionDeclarations,omitempty"`
	// GoogleSearchRetrieval: Optional. GoogleSearchRetrieval tool type.
	// Specialized retrieval tool that is powered by Google search.
	GoogleSearchRetrieval *GoogleCloudAiplatformV1beta1GoogleSearchRetrieval `json:"googleSearchRetrieval,omitempty"`
	// Retrieval: Optional. Retrieval tool type. System will always execute the
	// provided retrieval tool(s) to get external knowledge to answer the prompt.
	// Retrieval results are presented to the model for generation.
	Retrieval *GoogleCloudAiplatformV1beta1Retrieval `json:"retrieval,omitempty"`
	// ForceSendFields is a list of field names (e.g. "FunctionDeclarations") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "FunctionDeclarations") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1Tool) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1Tool
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1ToolConfig: Tool config. This config is shared
// for all tools provided in the request.
type GoogleCloudAiplatformV1beta1ToolConfig struct {
	// FunctionCallingConfig: Optional. Function calling config.
	FunctionCallingConfig *GoogleCloudAiplatformV1beta1FunctionCallingConfig `json:"functionCallingConfig,omitempty"`
	// ForceSendFields is a list of field names (e.g. "FunctionCallingConfig") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "FunctionCallingConfig") to
	// include in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1ToolConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1ToolConfig
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1VertexAISearch: Retrieve from Vertex AI Search
// datastore for grounding. See
// https://cloud.google.com/vertex-ai-search-and-conversation
type GoogleCloudAiplatformV1beta1VertexAISearch struct {
	// Datastore: Required. Fully-qualified Vertex AI Search's datastore resource
	// ID. Format:
	// `projects/{project}/locations/{location}/collections/{collection}/dataStores/
	// {dataStore}`
	Datastore string `json:"datastore,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Datastore") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Datastore") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1VertexAISearch) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1VertexAISearch
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1VertexRagStore: Retrieve from Vertex RAG Store
// for grounding.
type GoogleCloudAiplatformV1beta1VertexRagStore struct {
	// RagCorpora: Optional. Deprecated. Please use rag_resources instead.
	RagCorpora []string `json:"ragCorpora,omitempty"`
	// RagResources: Optional. The representation of the rag source. It can be used
	// to specify corpus only or ragfiles. Currently only support one corpus or
	// multiple files from one corpus. In the future we may open up multiple
	// corpora support.
	RagResources []*GoogleCloudAiplatformV1beta1VertexRagStoreRagResource `json:"ragResources,omitempty"`
	// SimilarityTopK: Optional. Number of top k results to return from the
	// selected corpora.
	SimilarityTopK int64 `json:"similarityTopK,omitempty"`
	// VectorDistanceThreshold: Optional. Only return results with vector distance
	// smaller than the threshold.
	VectorDistanceThreshold float64 `json:"vectorDistanceThreshold,omitempty"`
	// ForceSendFields is a list of field names (e.g. "RagCorpora") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "RagCorpora") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1VertexRagStore) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1VertexRagStore
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudAiplatformV1beta1VertexRagStore) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudAiplatformV1beta1VertexRagStore
	var s1 struct {
		VectorDistanceThreshold gensupport.JSONFloat64 `json:"vectorDistanceThreshold"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.VectorDistanceThreshold = float64(s1.VectorDistanceThreshold)
	return nil
}

// GoogleCloudAiplatformV1beta1VertexRagStoreRagResource: The definition of the
// Rag resource.
type GoogleCloudAiplatformV1beta1VertexRagStoreRagResource struct {
	// RagCorpus: Optional. RagCorpora resource name. Format:
	// `projects/{project}/locations/{location}/ragCorpora/{rag_corpus}`
	RagCorpus string `json:"ragCorpus,omitempty"`
	// RagFileIds: Optional. rag_file_id. The files should be in the same
	// rag_corpus set in rag_corpus field.
	RagFileIds []string `json:"ragFileIds,omitempty"`
	// ForceSendFields is a list of field names (e.g. "RagCorpus") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "RagCorpus") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1VertexRagStoreRagResource) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1VertexRagStoreRagResource
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudAiplatformV1beta1VideoMetadata: Metadata describes the input
// video content.
type GoogleCloudAiplatformV1beta1VideoMetadata struct {
	// EndOffset: Optional. The end offset of the video.
	EndOffset string `json:"endOffset,omitempty"`
	// StartOffset: Optional. The start offset of the video.
	StartOffset string `json:"startOffset,omitempty"`
	// ForceSendFields is a list of field names (e.g. "EndOffset") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "EndOffset") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudAiplatformV1beta1VideoMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAiplatformV1beta1VideoMetadata
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

// ModelOperationMetadata: This is returned in the longrunning operations for
// create/update.
type ModelOperationMetadata struct {
	// Possible values:
	//   "BASIC_OPERATION_STATUS_UNSPECIFIED" - The status is unspecified
	//   "BASIC_OPERATION_STATUS_UPLOADING" - The model file is being uploaded
	//   "BASIC_OPERATION_STATUS_VERIFYING" - The model file is being verified
	BasicOperationStatus string `json:"basicOperationStatus,omitempty"`
	// Name: The name of the model we are creating/updating The name must have the
	// form `projects/{project_id}/models/{model_id}`
	Name string `json:"name,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BasicOperationStatus") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "BasicOperationStatus") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s *ModelOperationMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod ModelOperationMetadata
	return gensupport.MarshalJSON(NoMethod(*s), s.ForceSendFields, s.NullFields)
}

type ProjectsLocationsPublishersModelsCountTokensCall struct {
	s                                              *Service
	endpoint                                       string
	googlecloudaiplatformv1beta1counttokensrequest *GoogleCloudAiplatformV1beta1CountTokensRequest
	urlParams_                                     gensupport.URLParams
	ctx_                                           context.Context
	header_                                        http.Header
}

// CountTokens: Perform a token counting.
//
//   - endpoint: The name of the Endpoint requested to perform token counting.
//     Format: `projects/{project}/locations/{location}/endpoints/{endpoint}`.
func (r *ProjectsLocationsPublishersModelsService) CountTokens(endpoint string, googlecloudaiplatformv1beta1counttokensrequest *GoogleCloudAiplatformV1beta1CountTokensRequest) *ProjectsLocationsPublishersModelsCountTokensCall {
	c := &ProjectsLocationsPublishersModelsCountTokensCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.endpoint = endpoint
	c.googlecloudaiplatformv1beta1counttokensrequest = googlecloudaiplatformv1beta1counttokensrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsPublishersModelsCountTokensCall) Fields(s ...googleapi.Field) *ProjectsLocationsPublishersModelsCountTokensCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsPublishersModelsCountTokensCall) Context(ctx context.Context) *ProjectsLocationsPublishersModelsCountTokensCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsPublishersModelsCountTokensCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsPublishersModelsCountTokensCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudaiplatformv1beta1counttokensrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2beta/{+endpoint}:countTokens")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"endpoint": c.endpoint,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "firebaseml.projects.locations.publishers.models.countTokens" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudAiplatformV1beta1CountTokensResponse.ServerResponse.Header or
// (if a response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ProjectsLocationsPublishersModelsCountTokensCall) Do(opts ...googleapi.CallOption) (*GoogleCloudAiplatformV1beta1CountTokensResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &GoogleCloudAiplatformV1beta1CountTokensResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
}

type ProjectsLocationsPublishersModelsGenerateContentCall struct {
	s                                                  *Service
	model                                              string
	googlecloudaiplatformv1beta1generatecontentrequest *GoogleCloudAiplatformV1beta1GenerateContentRequest
	urlParams_                                         gensupport.URLParams
	ctx_                                               context.Context
	header_                                            http.Header
}

// GenerateContent: Generate content with multimodal inputs.
//
//   - model: The name of the publisher model requested to serve the prediction.
//     Format: `projects/{project}/locations/{location}/publishers/*/models/*`.
func (r *ProjectsLocationsPublishersModelsService) GenerateContent(model string, googlecloudaiplatformv1beta1generatecontentrequest *GoogleCloudAiplatformV1beta1GenerateContentRequest) *ProjectsLocationsPublishersModelsGenerateContentCall {
	c := &ProjectsLocationsPublishersModelsGenerateContentCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.model = model
	c.googlecloudaiplatformv1beta1generatecontentrequest = googlecloudaiplatformv1beta1generatecontentrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsPublishersModelsGenerateContentCall) Fields(s ...googleapi.Field) *ProjectsLocationsPublishersModelsGenerateContentCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsPublishersModelsGenerateContentCall) Context(ctx context.Context) *ProjectsLocationsPublishersModelsGenerateContentCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsPublishersModelsGenerateContentCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsPublishersModelsGenerateContentCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudaiplatformv1beta1generatecontentrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2beta/{+model}:generateContent")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"model": c.model,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "firebaseml.projects.locations.publishers.models.generateContent" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudAiplatformV1beta1GenerateContentResponse.ServerResponse.Header
// or (if a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ProjectsLocationsPublishersModelsGenerateContentCall) Do(opts ...googleapi.CallOption) (*GoogleCloudAiplatformV1beta1GenerateContentResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &GoogleCloudAiplatformV1beta1GenerateContentResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
}

type ProjectsLocationsPublishersModelsStreamGenerateContentCall struct {
	s                                                  *Service
	model                                              string
	googlecloudaiplatformv1beta1generatecontentrequest *GoogleCloudAiplatformV1beta1GenerateContentRequest
	urlParams_                                         gensupport.URLParams
	ctx_                                               context.Context
	header_                                            http.Header
}

// StreamGenerateContent: Generate content with multimodal inputs with
// streaming support.
//
//   - model: The name of the publisher model requested to serve the prediction.
//     Format: `projects/{project}/locations/{location}/publishers/*/models/*`.
func (r *ProjectsLocationsPublishersModelsService) StreamGenerateContent(model string, googlecloudaiplatformv1beta1generatecontentrequest *GoogleCloudAiplatformV1beta1GenerateContentRequest) *ProjectsLocationsPublishersModelsStreamGenerateContentCall {
	c := &ProjectsLocationsPublishersModelsStreamGenerateContentCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.model = model
	c.googlecloudaiplatformv1beta1generatecontentrequest = googlecloudaiplatformv1beta1generatecontentrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsPublishersModelsStreamGenerateContentCall) Fields(s ...googleapi.Field) *ProjectsLocationsPublishersModelsStreamGenerateContentCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsPublishersModelsStreamGenerateContentCall) Context(ctx context.Context) *ProjectsLocationsPublishersModelsStreamGenerateContentCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsPublishersModelsStreamGenerateContentCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsPublishersModelsStreamGenerateContentCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudaiplatformv1beta1generatecontentrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2beta/{+model}:streamGenerateContent")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"model": c.model,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "firebaseml.projects.locations.publishers.models.streamGenerateContent" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudAiplatformV1beta1GenerateContentResponse.ServerResponse.Header
// or (if a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ProjectsLocationsPublishersModelsStreamGenerateContentCall) Do(opts ...googleapi.CallOption) (*GoogleCloudAiplatformV1beta1GenerateContentResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &GoogleCloudAiplatformV1beta1GenerateContentResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
}
