client icon indicating copy to clipboard operation
client copied to clipboard

How to get finishReason value

Open GeekTNT opened this issue 10 months ago • 8 comments

Hello,

I'm using

$input  = "Do something";
$client->geminiFlash()->generateContent($input);

And sometimes it fails with the following output (finishReason RECITATION):

It happens for eg. when I want to translate a text, that's copyrighted.

object(Gemini\Responses\GenerativeModel\GenerateContentResponse)#30 (3) {
  ["candidates"]=>
  array(1) {
    [0]=>
    object(Gemini\Data\Candidate)#25 (7) {
      ["content"]=>
      object(Gemini\Data\Content)#16 (2) {
        ["parts"]=>
        array(0) {
        }
        ["role"]=>
        enum(Gemini\Enums\Role::MODEL)
      }
      ["finishReason"]=>
      enum(Gemini\Enums\FinishReason::RECITATION)
      ["safetyRatings"]=>
      array(0) {
      }
      ["citationMetadata"]=>
      object(Gemini\Data\CitationMetadata)#31 (1) {
        ["citationSources"]=>
        array(4) {
...

More on the finishReason respones https://cloud.google.com/vertex-ai/generative-ai/docs/reference/python/latest/vertexai.generative_models.FinishReason

Is there a way to check the finishReason value. Or even better, can you make it so if the finishReason is not STOP to return the exception.

I can provide the content I used for the testing if needed.

Thank you.

GeekTNT avatar Feb 18 '25 12:02 GeekTNT

@GeekTNT I'm not the package maintainer, but I'm willing to look into this and make a PR if necessary.

Would you be able to provide a sample repo with steps to reproduce this?

Plytas avatar Mar 07 '25 16:03 Plytas

Thank you for your response.

I can't post the content used in here but I can email it to you if you are okay with that (to the email address from your github profile).

GeekTNT avatar Mar 07 '25 16:03 GeekTNT

Feel free to email me 👍

Plytas avatar Mar 07 '25 16:03 Plytas

Looking at the source code it seems that finish reason should already be available: https://github.com/gemini-api-php/client/blob/a48e61285d82b24117a5c8928dd1e504818f908b/src/Resources/Candidate.php#L26

Plytas avatar Mar 07 '25 16:03 Plytas

And it's value is just that: RECITATION. That comes directly from Gemini and there's nothing you can do about it. It just stop generating tokens.

Plytas avatar Mar 07 '25 16:03 Plytas

Sorry about the delay. I was away for a week or so.

Anyways, here's a very basic example of the code:

$client = Gemini::client($_api_key); $content = 'You are translator. Translate the text from English to Spanish...';

$result = $client->geminiFlash()->generateContent($content);

var_dump($result);

And I sometimes randomly get the following error: <b>Warning</b>: Undefined array key "startIndex" in <b>\vendor\google-gemini-php\client\src\Data\CitationSource.php</b> on line <b>35</b><br /> <br /> <b>Fatal error</b>: Uncaught TypeError: Gemini\Data\CitationSource::__construct(): Argument #1 ($startIndex) must be of type int, null given, called in \vendor\google-gemini-php\client\src\Data\CitationSource.php on line 38 and defined in \vendor\google-gemini-php\client\src\Data\CitationSource.php:22 Stack trace: #0 \vendor\google-gemini-php\client\src\Data\CitationSource.php(38): Gemini\Data\CitationSource-&gt;__construct(NULL, 143, 'https://macdown...', NULL) #1 \vendor\google-gemini-php\client\src\Data\CitationMetadata.php(29): Gemini\Data\CitationSource::from(Array) #2 [internal function]: Gemini\Data\CitationMetadata::Gemini\Data\{closure}(Array) #3 \vendor\google-gemini-php\client\src\Data\CitationMetadata.php(30): array_map(Object(Closure), Array) #4 \vendor\google-gemini-php\client\src\Data\Candidate.php(50): Gemini\Data\CitationMetadata::from(Array) #5 \vendor\google-gemini-php\client\src\Responses\GenerativeModel\GenerateContentResponse.php(96): Gemini\Data\Candidate::from(Array) #6 [internal function]: Gemini\Responses\GenerativeModel\GenerateContentResponse::Gemini\Responses\GenerativeModel\{closure}(Array) #7 \vendor\google-gemini-php\client\src\Responses\GenerativeModel\GenerateContentResponse.php(97): array_map(Object(Closure), Array) #8 \vendor\google-gemini-php\client\src\Resources\GenerativeModel.php(89): Gemini\Responses\GenerativeModel\GenerateContentResponse::from(Array) #9 \admin-win\_gemini_test.php(52): Gemini\Resources\GenerativeModel-&gt;generateContent('You are a trans...') #10 {main} thrown in <b>\vendor\google-gemini-php\client\src\Data\CitationSource.php</b> on line <b>22</b><br />

But sometimes I do get the "valid" result: object(Gemini\Responses\GenerativeModel\GenerateContentResponse)#28 (3) { ["candidates"]=> array(1) { [0]=> object(Gemini\Data\Candidate)#19 (7) { ["content"]=> object(Gemini\Data\Content)#26 (2) { ["parts"]=> array(0) { } ["role"]=> enum(Gemini\Enums\Role::USER) } ["finishReason"]=> enum(Gemini\Enums\FinishReason::RECITATION) ["safetyRatings"]=> array(0) { } ["citationMetadata"]=> object(Gemini\Data\CitationMetadata)#29 (1) { ["citationSources"]=> array(3) { [0]=> object(Gemini\Data\CitationSource)#24 (4) { ["startIndex"]=> int(1867) ["endIndex"]=> int(2007) ["uri"]=> NULL ["license"]=> NULL } [1]=> object(Gemini\Data\CitationSource)#18 (4) { ["startIndex"]=> int(2066) ["endIndex"]=> int(2229) ["uri"]=> string(62) "http://www.filehorse.com/es/descargar-dr-fone-toolkit-android/" ["license"]=> NULL } [2]=> object(Gemini\Data\CitationSource)#25 (4) { ["startIndex"]=> int(2362) ["endIndex"]=> int(2545) ["uri"]=> string(71) "https://www.lightbook.org/es/wondershare-dr-fone-toolkit-descargar.html" ["license"]=> NULL } } } ["index"]=> NULL ["tokenCount"]=> NULL ["avgLogprobs"]=> NULL } } ["usageMetadata"]=> object(Gemini\Data\UsageMetadata)#16 (4) { ["promptTokenCount"]=> int(2462) ["totalTokenCount"]=> int(2462) ["candidatesTokenCount"]=> NULL ["cachedContentTokenCount"]=> NULL } ["promptFeedback"]=> NULL }

Also, is there a better way to get finishReason than this: $finishReason = $result->candidates[0]->finishReason;

nemhal avatar Mar 21 '25 09:03 nemhal

@nemhal I think you are using a different package. Judging by your stack trace I think you are using https://github.com/google-gemini-php/client, but you posted this in https://github.com/gemini-api-php/client. I made this mistake myself before 😄

Looking at the package it seems that it expects startIndex and endIndex to always be present, but in docs it's optional. That package might need a PR to address that.

Or you could try switching to this package, looks like it handles nulls correctly in this case.

Plytas avatar Mar 21 '25 11:03 Plytas

Oh, I see 🤦‍♂️ Sorry about this. You can close/delete this one.

BTW: I tested this one and I have two issues with it:

  1. It lacks support for 2.0 models (that should be an easy fix).
  2. It returns finishReason "STOP" even when it sould be "RECITATION". The text is not translated and it just returns the original text.

nemhal avatar Mar 22 '25 18:03 nemhal