From 91122945e12429a25d53a1dd15aae3383aa49878 Mon Sep 17 00:00:00 2001 From: Josh Hoover Date: Fri, 30 Jun 2023 16:47:13 -0500 Subject: [PATCH 1/2] fix multiple function invocation --- src/createChat.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/createChat.ts b/src/createChat.ts index 10771c1..844d645 100644 --- a/src/createChat.ts +++ b/src/createChat.ts @@ -179,7 +179,7 @@ export const createChat = ( messages.push(omit(choice, "finishReason")); - if (choice.function_call) { + while (choice.function_call) { const functionName = choice.function_call.name; const userFunction = userFunctions[functionName]; @@ -203,6 +203,8 @@ export const createChat = ( }); choice = await complete(messageOptions); + + messages.push(omit(choice, "finishReason")); } // TypeScript can't properly narrow the type in the function body. From 98d697bfb0f59b5554fc64a0e55a722d46dc6978 Mon Sep 17 00:00:00 2001 From: Josh Hoover Date: Tue, 4 Jul 2023 21:07:46 -0500 Subject: [PATCH 2/2] Create test for multi function calling --- src/createChat.test.ts | 46 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/createChat.test.ts b/src/createChat.test.ts index 3da4447..0d6f34d 100644 --- a/src/createChat.test.ts +++ b/src/createChat.test.ts @@ -259,6 +259,52 @@ test("overrides function call", async () => { assert.equal(getCurrentWeather.mock.calls.length, 0); }); +test("calls a user defined function more than once", async () => { + const getCurrentWeather = mock.fn(({ location }: { location: string }) => { + return { + location, + temperature: "72", + unit: "fahrenheit", + forecast: ["sunny", "windy"], + }; + }); + + const chat = createChat({ + apiKey: OPENAI_API_KEY, + model: "gpt-3.5-turbo-0613", + functions: [ + { + name: "get_current_weather", + description: "Get the current weather in a given location", + parameters: { + type: "object", + properties: { + location: { + type: "string", + description: "The city and state, e.g. San Francisco, CA", + }, + unit: { type: "string", enum: ["celsius", "fahrenheit"] }, + }, + required: ["location"], + }, + function: getCurrentWeather, + }, + ], + }); + + await chat.sendMessage("Tell me the weather in Albuquerque and Chicago?"); + + assert.equal(getCurrentWeather.mock.calls.length, 2); + assert.equal( + getCurrentWeather.mock.calls[0].arguments[0].location, + "Albuquerque" + ); + assert.equal( + getCurrentWeather.mock.calls[1].arguments[0].location, + "Chicago" + ); +}); + test("overrides message options", async () => { const chat = createChat({ apiKey: OPENAI_API_KEY,