From ccdc4f8a4bd999d5e6ccc9d5c66c4f4720df8fa2 Mon Sep 17 00:00:00 2001 From: Christina Holland Date: Thu, 11 Apr 2024 10:38:30 -0700 Subject: [PATCH] Add systemInstruction and toolConfig (#89) --- ...ctioncallingconfig.allowedfunctionnames.md | 11 ++ .../generative-ai.functioncallingconfig.md | 20 +++ ...enerative-ai.functioncallingconfig.mode.md | 11 ++ .../generative-ai.functioncallingmode.md | 22 +++ .../generative-ai.generatecontentrequest.md | 2 + ...eneratecontentrequest.systeminstruction.md | 11 ++ ...ve-ai.generatecontentrequest.toolconfig.md | 11 ++ .../generative-ai.generativemodel.md | 2 + ...ve-ai.generativemodel.systeminstruction.md | 11 ++ ...enerative-ai.generativemodel.toolconfig.md | 11 ++ docs/reference/generative-ai.md | 3 + docs/reference/generative-ai.modelparams.md | 2 + ...rative-ai.modelparams.systeminstruction.md | 11 ++ .../generative-ai.modelparams.toolconfig.md | 11 ++ .../reference/generative-ai.possible_roles.md | 2 +- .../generative-ai.startchatparams.md | 2 + ...ve-ai.startchatparams.systeminstruction.md | 11 ++ ...enerative-ai.startchatparams.toolconfig.md | 11 ++ ...ive-ai.toolconfig.functioncallingconfig.md | 11 ++ docs/reference/generative-ai.toolconfig.md | 20 +++ .../main/src/methods/chat-session-helpers.ts | 4 + packages/main/src/methods/chat-session.ts | 4 + .../main/src/models/generative-model.test.ts | 162 +++++++++++++++++- packages/main/src/models/generative-model.ts | 12 ++ packages/main/types/enums.ts | 21 ++- packages/main/types/requests.ts | 29 +++- 26 files changed, 424 insertions(+), 4 deletions(-) create mode 100644 docs/reference/generative-ai.functioncallingconfig.allowedfunctionnames.md create mode 100644 docs/reference/generative-ai.functioncallingconfig.md create mode 100644 docs/reference/generative-ai.functioncallingconfig.mode.md create mode 100644 docs/reference/generative-ai.functioncallingmode.md create mode 100644 docs/reference/generative-ai.generatecontentrequest.systeminstruction.md create mode 100644 docs/reference/generative-ai.generatecontentrequest.toolconfig.md create mode 100644 docs/reference/generative-ai.generativemodel.systeminstruction.md create mode 100644 docs/reference/generative-ai.generativemodel.toolconfig.md create mode 100644 docs/reference/generative-ai.modelparams.systeminstruction.md create mode 100644 docs/reference/generative-ai.modelparams.toolconfig.md create mode 100644 docs/reference/generative-ai.startchatparams.systeminstruction.md create mode 100644 docs/reference/generative-ai.startchatparams.toolconfig.md create mode 100644 docs/reference/generative-ai.toolconfig.functioncallingconfig.md create mode 100644 docs/reference/generative-ai.toolconfig.md diff --git a/docs/reference/generative-ai.functioncallingconfig.allowedfunctionnames.md b/docs/reference/generative-ai.functioncallingconfig.allowedfunctionnames.md new file mode 100644 index 00000000..bb9ac0a1 --- /dev/null +++ b/docs/reference/generative-ai.functioncallingconfig.allowedfunctionnames.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [@google/generative-ai](./generative-ai.md) > [FunctionCallingConfig](./generative-ai.functioncallingconfig.md) > [allowedFunctionNames](./generative-ai.functioncallingconfig.allowedfunctionnames.md) + +## FunctionCallingConfig.allowedFunctionNames property + +**Signature:** + +```typescript +allowedFunctionNames?: string[]; +``` diff --git a/docs/reference/generative-ai.functioncallingconfig.md b/docs/reference/generative-ai.functioncallingconfig.md new file mode 100644 index 00000000..c41cd1e7 --- /dev/null +++ b/docs/reference/generative-ai.functioncallingconfig.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [@google/generative-ai](./generative-ai.md) > [FunctionCallingConfig](./generative-ai.functioncallingconfig.md) + +## FunctionCallingConfig interface + + +**Signature:** + +```typescript +export interface FunctionCallingConfig +``` + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [allowedFunctionNames?](./generative-ai.functioncallingconfig.allowedfunctionnames.md) | | string\[\] | _(Optional)_ | +| [mode?](./generative-ai.functioncallingconfig.mode.md) | | [FunctionCallingMode](./generative-ai.functioncallingmode.md) | _(Optional)_ | + diff --git a/docs/reference/generative-ai.functioncallingconfig.mode.md b/docs/reference/generative-ai.functioncallingconfig.mode.md new file mode 100644 index 00000000..12b0ee0d --- /dev/null +++ b/docs/reference/generative-ai.functioncallingconfig.mode.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [@google/generative-ai](./generative-ai.md) > [FunctionCallingConfig](./generative-ai.functioncallingconfig.md) > [mode](./generative-ai.functioncallingconfig.mode.md) + +## FunctionCallingConfig.mode property + +**Signature:** + +```typescript +mode?: FunctionCallingMode; +``` diff --git a/docs/reference/generative-ai.functioncallingmode.md b/docs/reference/generative-ai.functioncallingmode.md new file mode 100644 index 00000000..1cd91165 --- /dev/null +++ b/docs/reference/generative-ai.functioncallingmode.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [@google/generative-ai](./generative-ai.md) > [FunctionCallingMode](./generative-ai.functioncallingmode.md) + +## FunctionCallingMode enum + + +**Signature:** + +```typescript +export declare enum FunctionCallingMode +``` + +## Enumeration Members + +| Member | Value | Description | +| --- | --- | --- | +| ANY | "ANY" | | +| AUTO | "AUTO" | | +| MODE\_UNSPECIFIED | "MODE_UNSPECIFIED" | | +| NONE | "NONE" | | + diff --git a/docs/reference/generative-ai.generatecontentrequest.md b/docs/reference/generative-ai.generatecontentrequest.md index 017f0642..e3172d88 100644 --- a/docs/reference/generative-ai.generatecontentrequest.md +++ b/docs/reference/generative-ai.generatecontentrequest.md @@ -18,5 +18,7 @@ export interface GenerateContentRequest extends BaseParams | Property | Modifiers | Type | Description | | --- | --- | --- | --- | | [contents](./generative-ai.generatecontentrequest.contents.md) | | [Content](./generative-ai.content.md)\[\] | | +| [systemInstruction?](./generative-ai.generatecontentrequest.systeminstruction.md) | | [Content](./generative-ai.content.md) | _(Optional)_ | +| [toolConfig?](./generative-ai.generatecontentrequest.toolconfig.md) | | [ToolConfig](./generative-ai.toolconfig.md) | _(Optional)_ | | [tools?](./generative-ai.generatecontentrequest.tools.md) | | [Tool](./generative-ai.tool.md)\[\] | _(Optional)_ | diff --git a/docs/reference/generative-ai.generatecontentrequest.systeminstruction.md b/docs/reference/generative-ai.generatecontentrequest.systeminstruction.md new file mode 100644 index 00000000..9ee74a08 --- /dev/null +++ b/docs/reference/generative-ai.generatecontentrequest.systeminstruction.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [@google/generative-ai](./generative-ai.md) > [GenerateContentRequest](./generative-ai.generatecontentrequest.md) > [systemInstruction](./generative-ai.generatecontentrequest.systeminstruction.md) + +## GenerateContentRequest.systemInstruction property + +**Signature:** + +```typescript +systemInstruction?: Content; +``` diff --git a/docs/reference/generative-ai.generatecontentrequest.toolconfig.md b/docs/reference/generative-ai.generatecontentrequest.toolconfig.md new file mode 100644 index 00000000..ae5657c7 --- /dev/null +++ b/docs/reference/generative-ai.generatecontentrequest.toolconfig.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [@google/generative-ai](./generative-ai.md) > [GenerateContentRequest](./generative-ai.generatecontentrequest.md) > [toolConfig](./generative-ai.generatecontentrequest.toolconfig.md) + +## GenerateContentRequest.toolConfig property + +**Signature:** + +```typescript +toolConfig?: ToolConfig; +``` diff --git a/docs/reference/generative-ai.generativemodel.md b/docs/reference/generative-ai.generativemodel.md index 3bbd2007..fe992467 100644 --- a/docs/reference/generative-ai.generativemodel.md +++ b/docs/reference/generative-ai.generativemodel.md @@ -27,6 +27,8 @@ export declare class GenerativeModel | [model](./generative-ai.generativemodel.model.md) | | string | | | [requestOptions](./generative-ai.generativemodel.requestoptions.md) | | [RequestOptions](./generative-ai.requestoptions.md) | | | [safetySettings](./generative-ai.generativemodel.safetysettings.md) | | [SafetySetting](./generative-ai.safetysetting.md)\[\] | | +| [systemInstruction?](./generative-ai.generativemodel.systeminstruction.md) | | [Content](./generative-ai.content.md) | _(Optional)_ | +| [toolConfig?](./generative-ai.generativemodel.toolconfig.md) | | [ToolConfig](./generative-ai.toolconfig.md) | _(Optional)_ | | [tools?](./generative-ai.generativemodel.tools.md) | | [Tool](./generative-ai.tool.md)\[\] | _(Optional)_ | ## Methods diff --git a/docs/reference/generative-ai.generativemodel.systeminstruction.md b/docs/reference/generative-ai.generativemodel.systeminstruction.md new file mode 100644 index 00000000..652b0ec3 --- /dev/null +++ b/docs/reference/generative-ai.generativemodel.systeminstruction.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [@google/generative-ai](./generative-ai.md) > [GenerativeModel](./generative-ai.generativemodel.md) > [systemInstruction](./generative-ai.generativemodel.systeminstruction.md) + +## GenerativeModel.systemInstruction property + +**Signature:** + +```typescript +systemInstruction?: Content; +``` diff --git a/docs/reference/generative-ai.generativemodel.toolconfig.md b/docs/reference/generative-ai.generativemodel.toolconfig.md new file mode 100644 index 00000000..c536be62 --- /dev/null +++ b/docs/reference/generative-ai.generativemodel.toolconfig.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [@google/generative-ai](./generative-ai.md) > [GenerativeModel](./generative-ai.generativemodel.md) > [toolConfig](./generative-ai.generativemodel.toolconfig.md) + +## GenerativeModel.toolConfig property + +**Signature:** + +```typescript +toolConfig?: ToolConfig; +``` diff --git a/docs/reference/generative-ai.md b/docs/reference/generative-ai.md index e92ee919..2e39232b 100644 --- a/docs/reference/generative-ai.md +++ b/docs/reference/generative-ai.md @@ -18,6 +18,7 @@ | --- | --- | | [BlockReason](./generative-ai.blockreason.md) | Reason that a prompt was blocked. | | [FinishReason](./generative-ai.finishreason.md) | Reason that a candidate finished. | +| [FunctionCallingMode](./generative-ai.functioncallingmode.md) | | | [FunctionDeclarationSchemaType](./generative-ai.functiondeclarationschematype.md) | Contains the list of OpenAPI data types as defined by https://swagger.io/docs/specification/data-models/data-types/ | | [HarmBlockThreshold](./generative-ai.harmblockthreshold.md) | Threshold above which a prompt or candidate will be blocked. | | [HarmCategory](./generative-ai.harmcategory.md) | Harm categories that would cause prompts or candidates to be blocked. | @@ -41,6 +42,7 @@ | [EmbedContentResponse](./generative-ai.embedcontentresponse.md) | Response from calling [GenerativeModel.embedContent()](./generative-ai.generativemodel.embedcontent.md). | | [EnhancedGenerateContentResponse](./generative-ai.enhancedgeneratecontentresponse.md) | Response object wrapped with helper methods. | | [FunctionCall](./generative-ai.functioncall.md) | 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. | +| [FunctionCallingConfig](./generative-ai.functioncallingconfig.md) | | | [FunctionCallPart](./generative-ai.functioncallpart.md) | Content part interface if the part represents FunctionResponse. | | [FunctionDeclaration](./generative-ai.functiondeclaration.md) | 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. | | [FunctionDeclarationSchema](./generative-ai.functiondeclarationschema.md) | Schema for parameters passed to [FunctionDeclaration.parameters](./generative-ai.functiondeclaration.parameters.md). | @@ -63,6 +65,7 @@ | [SafetySetting](./generative-ai.safetysetting.md) | Safety setting that can be sent as part of request parameters. | | [StartChatParams](./generative-ai.startchatparams.md) | Params for [GenerativeModel.startChat()](./generative-ai.generativemodel.startchat.md). | | [TextPart](./generative-ai.textpart.md) | Content part interface if the part represents a text string. | +| [ToolConfig](./generative-ai.toolconfig.md) | Tool config. This config is shared for all tools provided in the request. | ## Variables diff --git a/docs/reference/generative-ai.modelparams.md b/docs/reference/generative-ai.modelparams.md index e6f1467d..7a2f9e0b 100644 --- a/docs/reference/generative-ai.modelparams.md +++ b/docs/reference/generative-ai.modelparams.md @@ -18,5 +18,7 @@ export interface ModelParams extends BaseParams | Property | Modifiers | Type | Description | | --- | --- | --- | --- | | [model](./generative-ai.modelparams.model.md) | | string | | +| [systemInstruction?](./generative-ai.modelparams.systeminstruction.md) | | [Content](./generative-ai.content.md) | _(Optional)_ | +| [toolConfig?](./generative-ai.modelparams.toolconfig.md) | | [ToolConfig](./generative-ai.toolconfig.md) | _(Optional)_ | | [tools?](./generative-ai.modelparams.tools.md) | | [Tool](./generative-ai.tool.md)\[\] | _(Optional)_ | diff --git a/docs/reference/generative-ai.modelparams.systeminstruction.md b/docs/reference/generative-ai.modelparams.systeminstruction.md new file mode 100644 index 00000000..ab170091 --- /dev/null +++ b/docs/reference/generative-ai.modelparams.systeminstruction.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [@google/generative-ai](./generative-ai.md) > [ModelParams](./generative-ai.modelparams.md) > [systemInstruction](./generative-ai.modelparams.systeminstruction.md) + +## ModelParams.systemInstruction property + +**Signature:** + +```typescript +systemInstruction?: Content; +``` diff --git a/docs/reference/generative-ai.modelparams.toolconfig.md b/docs/reference/generative-ai.modelparams.toolconfig.md new file mode 100644 index 00000000..8cc604d7 --- /dev/null +++ b/docs/reference/generative-ai.modelparams.toolconfig.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [@google/generative-ai](./generative-ai.md) > [ModelParams](./generative-ai.modelparams.md) > [toolConfig](./generative-ai.modelparams.toolconfig.md) + +## ModelParams.toolConfig property + +**Signature:** + +```typescript +toolConfig?: ToolConfig; +``` diff --git a/docs/reference/generative-ai.possible_roles.md b/docs/reference/generative-ai.possible_roles.md index 570d5bc8..b17cbf58 100644 --- a/docs/reference/generative-ai.possible_roles.md +++ b/docs/reference/generative-ai.possible_roles.md @@ -9,5 +9,5 @@ Possible roles. **Signature:** ```typescript -POSSIBLE_ROLES: readonly ["user", "model", "function"] +POSSIBLE_ROLES: readonly ["user", "model", "function", "system"] ``` diff --git a/docs/reference/generative-ai.startchatparams.md b/docs/reference/generative-ai.startchatparams.md index f901c5ed..b3559901 100644 --- a/docs/reference/generative-ai.startchatparams.md +++ b/docs/reference/generative-ai.startchatparams.md @@ -18,5 +18,7 @@ export interface StartChatParams extends BaseParams | Property | Modifiers | Type | Description | | --- | --- | --- | --- | | [history?](./generative-ai.startchatparams.history.md) | | [Content](./generative-ai.content.md)\[\] | _(Optional)_ | +| [systemInstruction?](./generative-ai.startchatparams.systeminstruction.md) | | [Content](./generative-ai.content.md) | _(Optional)_ | +| [toolConfig?](./generative-ai.startchatparams.toolconfig.md) | | [ToolConfig](./generative-ai.toolconfig.md) | _(Optional)_ | | [tools?](./generative-ai.startchatparams.tools.md) | | [Tool](./generative-ai.tool.md)\[\] | _(Optional)_ | diff --git a/docs/reference/generative-ai.startchatparams.systeminstruction.md b/docs/reference/generative-ai.startchatparams.systeminstruction.md new file mode 100644 index 00000000..1f540c2c --- /dev/null +++ b/docs/reference/generative-ai.startchatparams.systeminstruction.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [@google/generative-ai](./generative-ai.md) > [StartChatParams](./generative-ai.startchatparams.md) > [systemInstruction](./generative-ai.startchatparams.systeminstruction.md) + +## StartChatParams.systemInstruction property + +**Signature:** + +```typescript +systemInstruction?: Content; +``` diff --git a/docs/reference/generative-ai.startchatparams.toolconfig.md b/docs/reference/generative-ai.startchatparams.toolconfig.md new file mode 100644 index 00000000..f47d72ca --- /dev/null +++ b/docs/reference/generative-ai.startchatparams.toolconfig.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [@google/generative-ai](./generative-ai.md) > [StartChatParams](./generative-ai.startchatparams.md) > [toolConfig](./generative-ai.startchatparams.toolconfig.md) + +## StartChatParams.toolConfig property + +**Signature:** + +```typescript +toolConfig?: ToolConfig; +``` diff --git a/docs/reference/generative-ai.toolconfig.functioncallingconfig.md b/docs/reference/generative-ai.toolconfig.functioncallingconfig.md new file mode 100644 index 00000000..b89bbac6 --- /dev/null +++ b/docs/reference/generative-ai.toolconfig.functioncallingconfig.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [@google/generative-ai](./generative-ai.md) > [ToolConfig](./generative-ai.toolconfig.md) > [functionCallingConfig](./generative-ai.toolconfig.functioncallingconfig.md) + +## ToolConfig.functionCallingConfig property + +**Signature:** + +```typescript +functionCallingConfig: FunctionCallingConfig; +``` diff --git a/docs/reference/generative-ai.toolconfig.md b/docs/reference/generative-ai.toolconfig.md new file mode 100644 index 00000000..ebfb8b0d --- /dev/null +++ b/docs/reference/generative-ai.toolconfig.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [@google/generative-ai](./generative-ai.md) > [ToolConfig](./generative-ai.toolconfig.md) + +## ToolConfig interface + +Tool config. This config is shared for all tools provided in the request. + +**Signature:** + +```typescript +export interface ToolConfig +``` + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [functionCallingConfig](./generative-ai.toolconfig.functioncallingconfig.md) | | [FunctionCallingConfig](./generative-ai.functioncallingconfig.md) | | + diff --git a/packages/main/src/methods/chat-session-helpers.ts b/packages/main/src/methods/chat-session-helpers.ts index ed6fa0c7..bb154444 100644 --- a/packages/main/src/methods/chat-session-helpers.ts +++ b/packages/main/src/methods/chat-session-helpers.ts @@ -33,12 +33,16 @@ const VALID_PARTS_PER_ROLE: { [key in Role]: Array } = { user: ["text", "inlineData"], function: ["functionResponse"], model: ["text", "functionCall"], + // System instructions shouldn't be in history anyway. + system: ["text"], }; const VALID_PREVIOUS_CONTENT_ROLES: { [key in Role]: Role[] } = { user: ["model"], function: ["model"], model: ["user", "function"], + // System instructions shouldn't be in history. + system: [], }; export function validateChatHistory(history: Content[]): void { diff --git a/packages/main/src/methods/chat-session.ts b/packages/main/src/methods/chat-session.ts index 08da2e18..9b6e3335 100644 --- a/packages/main/src/methods/chat-session.ts +++ b/packages/main/src/methods/chat-session.ts @@ -81,6 +81,8 @@ export class ChatSession { safetySettings: this.params?.safetySettings, generationConfig: this.params?.generationConfig, tools: this.params?.tools, + toolConfig: this.params?.toolConfig, + systemInstruction: this.params?.systemInstruction, contents: [...this._history, newContent], }; let finalResult; @@ -135,6 +137,8 @@ export class ChatSession { safetySettings: this.params?.safetySettings, generationConfig: this.params?.generationConfig, tools: this.params?.tools, + toolConfig: this.params?.toolConfig, + systemInstruction: this.params?.systemInstruction, contents: [...this._history, newContent], }; const streamPromise = generateContentStream( diff --git a/packages/main/src/models/generative-model.test.ts b/packages/main/src/models/generative-model.test.ts index b8435051..254d3712 100644 --- a/packages/main/src/models/generative-model.test.ts +++ b/packages/main/src/models/generative-model.test.ts @@ -14,8 +14,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { expect } from "chai"; +import { expect, use } from "chai"; import { GenerativeModel } from "./generative-model"; +import * as sinonChai from "sinon-chai"; +import { FunctionCallingMode } from "../../types"; +import { getMockResponse } from "../../test-utils/mock-response"; +import { match, restore, stub } from "sinon"; +import * as request from "../requests/request"; + +use(sinonChai); describe("GenerativeModel", () => { it("handles plain model name", () => { @@ -34,4 +41,157 @@ describe("GenerativeModel", () => { }); expect(genModel.model).to.equal("tunedModels/my-model"); }); + it("passes params through to generateContent", async () => { + const genModel = new GenerativeModel("apiKey", { + model: "my-model", + tools: [{ functionDeclarations: [{ name: "myfunc" }] }], + toolConfig: { functionCallingConfig: { mode: FunctionCallingMode.NONE } }, + systemInstruction: { role: "system", parts: [{ text: "be friendly" }] }, + }); + expect(genModel.tools?.length).to.equal(1); + expect(genModel.toolConfig?.functionCallingConfig.mode).to.equal( + FunctionCallingMode.NONE, + ); + expect(genModel.systemInstruction?.parts[0].text).to.equal("be friendly"); + const mockResponse = getMockResponse( + "unary-success-basic-reply-short.json", + ); + const makeRequestStub = stub(request, "makeRequest").resolves( + mockResponse as Response, + ); + await genModel.generateContent("hello"); + expect(makeRequestStub).to.be.calledWith( + "models/my-model", + request.Task.GENERATE_CONTENT, + match.any, + false, + match((value: string) => { + return ( + value.includes("myfunc") && + value.includes(FunctionCallingMode.NONE) && + value.includes("be friendly") + ); + }), + {}, + ); + restore(); + }); + it("generateContent overrides model values", async () => { + const genModel = new GenerativeModel("apiKey", { + model: "my-model", + tools: [{ functionDeclarations: [{ name: "myfunc" }] }], + toolConfig: { functionCallingConfig: { mode: FunctionCallingMode.NONE } }, + systemInstruction: { role: "system", parts: [{ text: "be friendly" }] }, + }); + expect(genModel.tools?.length).to.equal(1); + expect(genModel.toolConfig?.functionCallingConfig.mode).to.equal( + FunctionCallingMode.NONE, + ); + expect(genModel.systemInstruction?.parts[0].text).to.equal("be friendly"); + const mockResponse = getMockResponse( + "unary-success-basic-reply-short.json", + ); + const makeRequestStub = stub(request, "makeRequest").resolves( + mockResponse as Response, + ); + await genModel.generateContent({ + contents: [{ role: "user", parts: [{ text: "hello" }] }], + tools: [{ functionDeclarations: [{ name: "otherfunc" }] }], + toolConfig: { functionCallingConfig: { mode: FunctionCallingMode.AUTO } }, + systemInstruction: { role: "system", parts: [{ text: "be formal" }] }, + }); + expect(makeRequestStub).to.be.calledWith( + "models/my-model", + request.Task.GENERATE_CONTENT, + match.any, + false, + match((value: string) => { + return ( + value.includes("otherfunc") && + value.includes(FunctionCallingMode.AUTO) && + value.includes("be formal") + ); + }), + {}, + ); + restore(); + }); + it("passes params through to chat.sendMessage", async () => { + const genModel = new GenerativeModel("apiKey", { + model: "my-model", + tools: [{ functionDeclarations: [{ name: "myfunc" }] }], + toolConfig: { functionCallingConfig: { mode: FunctionCallingMode.NONE } }, + systemInstruction: { role: "system", parts: [{ text: "be friendly" }] }, + }); + expect(genModel.tools?.length).to.equal(1); + expect(genModel.toolConfig?.functionCallingConfig.mode).to.equal( + FunctionCallingMode.NONE, + ); + expect(genModel.systemInstruction?.parts[0].text).to.equal("be friendly"); + const mockResponse = getMockResponse( + "unary-success-basic-reply-short.json", + ); + const makeRequestStub = stub(request, "makeRequest").resolves( + mockResponse as Response, + ); + await genModel.startChat().sendMessage("hello"); + expect(makeRequestStub).to.be.calledWith( + "models/my-model", + request.Task.GENERATE_CONTENT, + match.any, + false, + match((value: string) => { + return ( + value.includes("myfunc") && + value.includes(FunctionCallingMode.NONE) && + value.includes("be friendly") + ); + }), + {}, + ); + restore(); + }); + it("startChat overrides model values", async () => { + const genModel = new GenerativeModel("apiKey", { + model: "my-model", + tools: [{ functionDeclarations: [{ name: "myfunc" }] }], + toolConfig: { functionCallingConfig: { mode: FunctionCallingMode.NONE } }, + systemInstruction: { role: "system", parts: [{ text: "be friendly" }] }, + }); + expect(genModel.tools?.length).to.equal(1); + expect(genModel.toolConfig?.functionCallingConfig.mode).to.equal( + FunctionCallingMode.NONE, + ); + expect(genModel.systemInstruction?.parts[0].text).to.equal("be friendly"); + const mockResponse = getMockResponse( + "unary-success-basic-reply-short.json", + ); + const makeRequestStub = stub(request, "makeRequest").resolves( + mockResponse as Response, + ); + await genModel + .startChat({ + tools: [{ functionDeclarations: [{ name: "otherfunc" }] }], + toolConfig: { + functionCallingConfig: { mode: FunctionCallingMode.AUTO }, + }, + systemInstruction: { role: "system", parts: [{ text: "be formal" }] }, + }) + .sendMessage("hello"); + expect(makeRequestStub).to.be.calledWith( + "models/my-model", + request.Task.GENERATE_CONTENT, + match.any, + false, + match((value: string) => { + return ( + value.includes("otherfunc") && + value.includes(FunctionCallingMode.AUTO) && + value.includes("be formal") + ); + }), + {}, + ); + restore(); + }); }); diff --git a/packages/main/src/models/generative-model.ts b/packages/main/src/models/generative-model.ts index 3ca5a3ef..d2e1b2e3 100644 --- a/packages/main/src/models/generative-model.ts +++ b/packages/main/src/models/generative-model.ts @@ -22,6 +22,7 @@ import { import { BatchEmbedContentsRequest, BatchEmbedContentsResponse, + Content, CountTokensRequest, CountTokensResponse, EmbedContentRequest, @@ -36,6 +37,7 @@ import { SafetySetting, StartChatParams, Tool, + ToolConfig, } from "../../types"; import { ChatSession } from "../methods/chat-session"; import { countTokens } from "../methods/count-tokens"; @@ -55,6 +57,8 @@ export class GenerativeModel { safetySettings: SafetySetting[]; requestOptions: RequestOptions; tools?: Tool[]; + toolConfig?: ToolConfig; + systemInstruction?: Content; constructor( public apiKey: string, @@ -71,6 +75,8 @@ export class GenerativeModel { this.generationConfig = modelParams.generationConfig || {}; this.safetySettings = modelParams.safetySettings || []; this.tools = modelParams.tools; + this.toolConfig = modelParams.toolConfig; + this.systemInstruction = modelParams.systemInstruction; this.requestOptions = requestOptions || {}; } @@ -89,6 +95,8 @@ export class GenerativeModel { generationConfig: this.generationConfig, safetySettings: this.safetySettings, tools: this.tools, + toolConfig: this.toolConfig, + systemInstruction: this.systemInstruction, ...formattedParams, }, this.requestOptions, @@ -112,6 +120,8 @@ export class GenerativeModel { generationConfig: this.generationConfig, safetySettings: this.safetySettings, tools: this.tools, + toolConfig: this.toolConfig, + systemInstruction: this.systemInstruction, ...formattedParams, }, this.requestOptions, @@ -128,6 +138,8 @@ export class GenerativeModel { this.model, { tools: this.tools, + toolConfig: this.toolConfig, + systemInstruction: this.systemInstruction, ...startChatParams, }, this.requestOptions, diff --git a/packages/main/types/enums.ts b/packages/main/types/enums.ts index 2e089607..fef01de8 100644 --- a/packages/main/types/enums.ts +++ b/packages/main/types/enums.ts @@ -19,7 +19,7 @@ * Possible roles. * @public */ -export const POSSIBLE_ROLES = ["user", "model", "function"] as const; +export const POSSIBLE_ROLES = ["user", "model", "function", "system"] as const; /** * Harm categories that would cause prompts or candidates to be blocked. @@ -111,3 +111,22 @@ export enum TaskType { CLASSIFICATION = "CLASSIFICATION", CLUSTERING = "CLUSTERING", } + +/** + * @public + */ +export enum FunctionCallingMode { + // Unspecified function calling mode. This value should not be used. + MODE_UNSPECIFIED = "MODE_UNSPECIFIED", + // Default model behavior, model decides to predict either a function call + // or a natural language repspose. + AUTO = "AUTO", + // 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". + ANY = "ANY", + // Model will not predict any function call. Model behavior is same as when + // not passing any function declarations. + NONE = "NONE", +} diff --git a/packages/main/types/requests.ts b/packages/main/types/requests.ts index ffc5d94f..ba3bd3ea 100644 --- a/packages/main/types/requests.ts +++ b/packages/main/types/requests.ts @@ -16,7 +16,12 @@ */ import { Content } from "./content"; -import { HarmBlockThreshold, HarmCategory, TaskType } from "./enums"; +import { + FunctionCallingMode, + HarmBlockThreshold, + HarmCategory, + TaskType, +} from "./enums"; /** * Base parameters for a number of methods. @@ -34,6 +39,8 @@ export interface BaseParams { export interface ModelParams extends BaseParams { model: string; tools?: Tool[]; + toolConfig?: ToolConfig; + systemInstruction?: Content; } /** @@ -43,6 +50,8 @@ export interface ModelParams extends BaseParams { export interface GenerateContentRequest extends BaseParams { contents: Content[]; tools?: Tool[]; + toolConfig?: ToolConfig; + systemInstruction?: Content; } /** @@ -74,6 +83,8 @@ export interface GenerationConfig { export interface StartChatParams extends BaseParams { history?: Content[]; tools?: Tool[]; + toolConfig?: ToolConfig; + systemInstruction?: Content; } /** @@ -260,3 +271,19 @@ export interface FunctionDeclarationSchemaProperty { /** Optional. The example of the property. */ example?: unknown; } + +/** + * Tool config. This config is shared for all tools provided in the request. + * @public + */ +export interface ToolConfig { + functionCallingConfig: FunctionCallingConfig; +} + +/** + * @public + */ +export interface FunctionCallingConfig { + mode?: FunctionCallingMode; + allowedFunctionNames?: string[]; +}