googleapis / googleapis/google-cloud-php

[PredictionServiceClient] Bug in embedContent and EmbedContentRequest: Invalid model/endpoint mappings causing INVALID_ARGUMENT or undefined method errors

Open
#9,276 1 comment 1 reaction 0 assignees View on GitHub
Dominant language
PHP
Stars
1.2k
Forks
463
Avg merge
2d 1h
Merged PRs (30d)
145

Description

When attempting to use PredictionServiceClient::embedContent() with the newer EmbedContentRequest class, the underlying gRPC bindings fail to resolve the model or endpoint correctly. This makes it impossible to use the native text-embedding endpoints via the official PHP SDK.

Steps to reproduce:
If we try to construct the request by setting the model using setModel():

```php
use Google\Cloud\AIPlatform\V1\Client\PredictionServiceClient;
use Google\Cloud\AIPlatform\V1\EmbedContentRequest;
use Google\Cloud\AIPlatform\V1\Content;
use Google\Cloud\AIPlatform\V1\Part;

$client = new PredictionServiceClient([
'apiEndpoint' => 'us-central1-aiplatform.googleapis.com',
'credentials' => '/path/to/credentials.json'
]);

$content = (new Content())->setParts([(new Part())->setText('Hello world')]);

$req = new EmbedContentRequest();
$req->setModel('projects/MY_PROJECT/locations/us-central1/publishers/google/models/text-embedding-004');
$req->setContent($content);

$res = $client->embedContent($req);
```

Actual Result: An ApiException is thrown from the backend:
```json
{
"message": "Invalid value (oneof), oneof field '_model' is already set. Cannot set 'model'",
"code": 3,
"status": "INVALID_ARGUMENT",
"details": [ ... ]
}
```

If we try to supply an endpoint via the $optionalArgs to bypass the model binding:
```php
$res = $client->embedContent($req, [
'endpoint' => 'projects/MY_PROJECT/locations/us-central1/publishers/google/models/text-embedding-004'
]);
```

Actual Result:
```
Google\ApiCore\ValidationException: Could not map bindings for google.cloud.aiplatform.v1.PredictionService/EmbedContent to any Uri template.
```

If we attempt to use setEndpoint() on the request object itself (which is available on PredictRequest but seems to be missing here):
```php
$req->setEndpoint('projects/MY_PROJECT/locations/us-central1/publishers/google/models/text-embedding-004');
```

Actual Result:
```
Fatal error: Call to undefined method Google\Cloud\AIPlatform\V1\EmbedContentRequest::setEndpoint()
```

Expected Result:
The EmbedContentRequest should properly bind the model parameter to the gRPC URI template (e.g. /v1/{model=projects/*/locations/*/publishers/*/models/*}:embedContent) without throwing a protobuf oneof conflict (_model vs model), and should successfully return the EmbedContentResponse.

Workaround (for others facing this issue):

Currently, the only way to get embeddings via PHP is to bypass EmbedContentRequest and use the older PredictRequest with raw Protobuf Structs:
```php
$instanceValue = new \Google\Protobuf\Value();
$struct = new \Google\Protobuf\Struct();
$struct->setFields(['content' => (new \Google\Protobuf\Value())->setStringValue('Hello World')]);
$instanceValue->setStructValue($struct);

$request = (new PredictRequest())
->setEndpoint('projects/MY_PROJECT/locations/us-central1/publishers/google/models/text-embedding-004')
->setInstances([$instanceValue]);

$response = $client->predict($request);
```
Environment details:
OS: Linux
PHP version: 8.0+
Package name and version: google/cloud-ai-platform (Tested on versions ^1.13.0 up to 1.60.1)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.