Skip to content

Commit

Permalink
functionCall => functionCalls (#75)
Browse files Browse the repository at this point in the history
  • Loading branch information
hsubox76 authored Apr 3, 2024
1 parent 7a45f01 commit 790a943
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/nice-toes-check.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@google/generative-ai": minor
---

Deprecate functionCall() and add functionCalls().
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@

## EnhancedGenerateContentResponse.functionCall property

> Warning: This API is now obsolete.
>
>
Deprecated: use `functionCalls()` instead.

**Signature:**

```typescript
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@google/generative-ai](./generative-ai.md) &gt; [EnhancedGenerateContentResponse](./generative-ai.enhancedgeneratecontentresponse.md) &gt; [functionCalls](./generative-ai.enhancedgeneratecontentresponse.functioncalls.md)

## EnhancedGenerateContentResponse.functionCalls property

Returns function calls found in any `Part`<!-- -->s of the first candidate of the response, if available. Throws if the prompt or candidate was blocked.

**Signature:**

```typescript
functionCalls: () => FunctionCall[] | undefined;
```
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface EnhancedGenerateContentResponse extends GenerateContentResponse
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [functionCall](./generative-ai.enhancedgeneratecontentresponse.functioncall.md) | | () =&gt; [FunctionCall](./generative-ai.functioncall.md) \| undefined | |
| [text](./generative-ai.enhancedgeneratecontentresponse.text.md) | | () =&gt; string | Returns the text string from the response, if available. Throws if the prompt or candidate was blocked. |
| [functionCall](./generative-ai.enhancedgeneratecontentresponse.functioncall.md) | | () =&gt; [FunctionCall](./generative-ai.functioncall.md) \| undefined | Deprecated: use <code>functionCalls()</code> instead. |
| [functionCalls](./generative-ai.enhancedgeneratecontentresponse.functioncalls.md) | | () =&gt; [FunctionCall](./generative-ai.functioncall.md)<!-- -->\[\] \| undefined | Returns function calls found in any <code>Part</code>s of the first candidate of the response, if available. Throws if the prompt or candidate was blocked. |
| [text](./generative-ai.enhancedgeneratecontentresponse.text.md) | | () =&gt; string | Returns the text string assembled from all <code>Part</code>s of the first candidate of the response, if available. Throws if the prompt or candidate was blocked. |
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## EnhancedGenerateContentResponse.text property

Returns the text string from the response, if available. Throws if the prompt or candidate was blocked.
Returns the text string assembled from all `Part`<!-- -->s of the first candidate of the response, if available. Throws if the prompt or candidate was blocked.

**Signature:**

Expand Down
40 changes: 40 additions & 0 deletions packages/main/src/requests/response-helpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const fakeResponseText: GenerateContentResponse = {
},
],
};

const fakeResponseFunctionCall: GenerateContentResponse = {
candidates: [
{
Expand All @@ -61,6 +62,38 @@ const fakeResponseFunctionCall: GenerateContentResponse = {
],
};

const fakeResponseFunctionCalls: GenerateContentResponse = {
candidates: [
{
index: 0,
content: {
role: "model",
parts: [
{
functionCall: {
name: "find_theaters",
args: {
location: "Mountain View, CA",
movie: "Barbie",
},
},
},
{
functionCall: {
name: "find_times",
args: {
location: "Mountain View, CA",
movie: "Barbie",
time: "20:00",
},
},
},
],
},
},
],
};

const badFakeResponse: GenerateContentResponse = {
promptFeedback: {
blockReason: BlockReason.SAFETY,
Expand All @@ -83,6 +116,13 @@ describe("response-helpers methods", () => {
fakeResponseFunctionCall.candidates[0].content.parts[0].functionCall,
);
});
it("good response functionCalls", async () => {
const enhancedResponse = addHelpers(fakeResponseFunctionCalls);
expect(enhancedResponse.functionCalls()).to.deep.equal([
fakeResponseFunctionCalls.candidates[0].content.parts[0].functionCall,
fakeResponseFunctionCalls.candidates[0].content.parts[1].functionCall,
]);
});
it("bad response safety", async () => {
const enhancedResponse = addHelpers(badFakeResponse);
expect(enhancedResponse.text).to.throw("SAFETY");
Expand Down
53 changes: 48 additions & 5 deletions packages/main/src/requests/response-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,15 @@ export function addHelpers(
}
return "";
};
/**
* TODO: remove at next major version
*/
(response as EnhancedGenerateContentResponse).functionCall = () => {
if (response.candidates && response.candidates.length > 0) {
if (response.candidates.length > 1) {
console.warn(
`This response had ${response.candidates.length} ` +
`candidates. Returning function call from the first candidate only. ` +
`candidates. Returning function calls from the first candidate only. ` +
`Access response.candidates directly to use the other candidates.`,
);
}
Expand All @@ -70,7 +73,35 @@ export function addHelpers(
response,
);
}
return getFunctionCall(response);
console.warn(
`response.functionCall() is deprecated. ` +
`Use response.functionCalls() instead.`,
);
return getFunctionCalls(response)[0];
} else if (response.promptFeedback) {
throw new GoogleGenerativeAIResponseError<GenerateContentResponse>(
`Function call not available. ${formatBlockErrorMessage(response)}`,
response,
);
}
return undefined;
};
(response as EnhancedGenerateContentResponse).functionCalls = () => {
if (response.candidates && response.candidates.length > 0) {
if (response.candidates.length > 1) {
console.warn(
`This response had ${response.candidates.length} ` +
`candidates. Returning function calls from the first candidate only. ` +
`Access response.candidates directly to use the other candidates.`,
);
}
if (hadBadFinishReason(response.candidates[0])) {
throw new GoogleGenerativeAIResponseError<GenerateContentResponse>(
`${formatBlockErrorMessage(response)}`,
response,
);
}
return getFunctionCalls(response);
} else if (response.promptFeedback) {
throw new GoogleGenerativeAIResponseError<GenerateContentResponse>(
`Function call not available. ${formatBlockErrorMessage(response)}`,
Expand Down Expand Up @@ -98,10 +129,22 @@ export function getText(response: GenerateContentResponse): string {
/**
* Returns functionCall of first candidate.
*/
export function getFunctionCall(
export function getFunctionCalls(
response: GenerateContentResponse,
): FunctionCall {
return response.candidates?.[0].content?.parts?.[0]?.functionCall;
): FunctionCall[] {
const functionCalls: FunctionCall[] = [];
if (response.candidates?.[0].content?.parts) {
for (const part of response.candidates?.[0].content?.parts) {
if (part.functionCall) {
functionCalls.push(part.functionCall);
}
}
}
if (functionCalls.length > 0) {
return functionCalls;
} else {
return undefined;
}
}

const badFinishReasons = [FinishReason.RECITATION, FinishReason.SAFETY];
Expand Down
13 changes: 12 additions & 1 deletion packages/main/types/responses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,22 @@ export interface GenerateContentStreamResult {
export interface EnhancedGenerateContentResponse
extends GenerateContentResponse {
/**
* Returns the text string from the response, if available.
* Returns the text string assembled from all `Part`s of the first candidate
* of the response, if available.
* Throws if the prompt or candidate was blocked.
*/
text: () => string;
/**
* Deprecated: use `functionCalls()` instead.
* @deprecated
*/
functionCall: () => FunctionCall | undefined;
/**
* Returns function calls found in any `Part`s of the first candidate
* of the response, if available.
* Throws if the prompt or candidate was blocked.
*/
functionCalls: () => FunctionCall[] | undefined;
}

/**
Expand Down

0 comments on commit 790a943

Please sign in to comment.