@@ -32,11 +32,16 @@ import (
3232 "github.com/openai/openai-go/v3/packages/param"
3333)
3434
35+ const (
36+ functionNameGetWeather = "get_weather"
37+ functionNameGetTemperature = "get_temperature"
38+ )
39+
3540var tools = []openai.ChatCompletionToolUnionParam {
3641 {
3742 OfFunction : & openai.ChatCompletionFunctionToolParam {
3843 Function : openai.FunctionDefinitionParam {
39- Name : "get_weather" ,
44+ Name : functionNameGetWeather ,
4045 Description : openai .String ("Get weather at the given location" ),
4146 Parameters : openai.FunctionParameters {
4247 "type" : "object" ,
@@ -53,7 +58,7 @@ var tools = []openai.ChatCompletionToolUnionParam{
5358 {
5459 OfFunction : & openai.ChatCompletionFunctionToolParam {
5560 Function : openai.FunctionDefinitionParam {
56- Name : "get_temperature" ,
61+ Name : functionNameGetTemperature ,
5762 Description : openai .String ("Get temperature at the given location" ),
5863 Parameters : openai.FunctionParameters {
5964 "type" : "object" ,
@@ -78,7 +83,7 @@ var invalidTools = [][]openai.ChatCompletionToolUnionParam{
7883 {
7984 OfFunction : & openai.ChatCompletionFunctionToolParam {
8085 Function : openai.FunctionDefinitionParam {
81- Name : "get_weather" ,
86+ Name : functionNameGetWeather ,
8287 Description : openai .String ("Get weather at the given location" ),
8388 Parameters : openai.FunctionParameters {
8489 "type" : "object" ,
@@ -95,7 +100,7 @@ var invalidTools = [][]openai.ChatCompletionToolUnionParam{
95100 {
96101 OfFunction : & openai.ChatCompletionFunctionToolParam {
97102 Function : openai.FunctionDefinitionParam {
98- Name : "get_temperature" ,
103+ Name : functionNameGetTemperature ,
99104 Description : openai .String ("Get temperature at the given location" ),
100105 Parameters : openai.FunctionParameters {
101106 "type" : "object" ,
@@ -119,7 +124,7 @@ var invalidTools = [][]openai.ChatCompletionToolUnionParam{
119124 {
120125 OfFunction : & openai.ChatCompletionFunctionToolParam {
121126 Function : openai.FunctionDefinitionParam {
122- Name : "get_weather" ,
127+ Name : functionNameGetWeather ,
123128 Description : openai .String ("Get weather at the given location" ),
124129 Parameters : openai.FunctionParameters {
125130 "type" : "object" ,
@@ -139,7 +144,7 @@ var invalidTools = [][]openai.ChatCompletionToolUnionParam{
139144 {
140145 OfFunction : & openai.ChatCompletionFunctionToolParam {
141146 Function : openai.FunctionDefinitionParam {
142- Name : "get_weather" ,
147+ Name : functionNameGetWeather ,
143148 Description : openai .String ("Get weather at the given location" ),
144149 },
145150 },
@@ -312,7 +317,7 @@ var toolWithoutRequiredParams = []openai.ChatCompletionToolUnionParam{
312317 {
313318 OfFunction : & openai.ChatCompletionFunctionToolParam {
314319 Function : openai.FunctionDefinitionParam {
315- Name : "get_temperature" ,
320+ Name : functionNameGetTemperature ,
316321 Description : openai .String ("Get temperature at the given location" ),
317322 Parameters : openai.FunctionParameters {
318323 "type" : "object" ,
@@ -398,7 +403,7 @@ var _ = Describe("Simulator for request with tools", func() {
398403 tc := toolCalls [0 ]
399404 Expect (tc .Index ).To (Or (BeNumerically ("==" , lastIndex ), BeNumerically ("==" , lastIndex + 1 )))
400405 if tc .Index > int64 (lastIndex ) {
401- Expect (tc .Function .Name ).To (Or (Equal ("get_weather" ), Equal ("get_temperature" )))
406+ Expect (tc .Function .Name ).To (Or (Equal (functionNameGetWeather ), Equal (functionNameGetTemperature )))
402407 lastIndex ++
403408 args [tc .Function .Name ] = []string {tc .Function .Arguments }
404409 functionName = tc .Function .Name
@@ -429,7 +434,7 @@ var _ = Describe("Simulator for request with tools", func() {
429434 err := json .Unmarshal ([]byte (joinedArgs ), & argsMap )
430435 Expect (err ).NotTo (HaveOccurred ())
431436
432- if functionName == "get_weather" {
437+ if functionName == functionNameGetWeather {
433438 Expect (joinedArgs ).To (ContainSubstring ("location" ))
434439 } else {
435440 Expect (joinedArgs ).To (ContainSubstring ("city" ))
@@ -473,14 +478,14 @@ var _ = Describe("Simulator for request with tools", func() {
473478 toolCalls := resp .Choices [0 ].Message .ToolCalls
474479 Expect (toolCalls ).ToNot (BeEmpty ())
475480 for _ , tc := range toolCalls {
476- Expect (tc .Function .Name ).To (Or (Equal ("get_weather" ), Equal ("get_temperature" )))
481+ Expect (tc .Function .Name ).To (Or (Equal (functionNameGetWeather ), Equal (functionNameGetTemperature )))
477482 Expect (tc .ID ).NotTo (BeEmpty ())
478483 Expect (tc .Type ).To (Equal ("function" ))
479484 args := make (map [string ]string )
480485 err := json .Unmarshal ([]byte (tc .Function .Arguments ), & args )
481486 Expect (err ).NotTo (HaveOccurred ())
482487
483- if tc .Function .Name == "get_weather" {
488+ if tc .Function .Name == functionNameGetWeather {
484489 Expect (tc .Function .Arguments ).To (ContainSubstring ("location" ))
485490 } else {
486491 Expect (tc .Function .Arguments ).To (ContainSubstring ("city" ))
@@ -499,6 +504,59 @@ var _ = Describe("Simulator for request with tools", func() {
499504 Entry (nil , common .ModeRandom ),
500505 )
501506
507+ DescribeTable ("no streaming, a specific tool" ,
508+ func (mode string , specificTool string ) {
509+ ctx := context .TODO ()
510+ client , err := startServer (ctx , mode )
511+ Expect (err ).NotTo (HaveOccurred ())
512+
513+ openaiclient , params := getOpenAIClientAndChatParams (client , model , userMessage , false )
514+ params .ToolChoice = openai .ToolChoiceOptionFunctionToolChoice (openai.ChatCompletionNamedToolChoiceFunctionParam {
515+ Name : specificTool ,
516+ })
517+ params .Tools = tools
518+
519+ resp , err := openaiclient .Chat .Completions .New (ctx , params )
520+ Expect (err ).NotTo (HaveOccurred ())
521+ Expect (resp .Choices ).ShouldNot (BeEmpty ())
522+ Expect (string (resp .Object )).To (Equal (chatCompletionObject ))
523+
524+ Expect (resp .Usage .PromptTokens ).To (Equal (userMsgTokens ))
525+ Expect (resp .Usage .CompletionTokens ).To (BeNumerically (">" , 0 ))
526+ Expect (resp .Usage .TotalTokens ).To (Equal (resp .Usage .PromptTokens + resp .Usage .CompletionTokens ))
527+
528+ content := resp .Choices [0 ].Message .Content
529+ Expect (content ).Should (BeEmpty ())
530+
531+ toolCalls := resp .Choices [0 ].Message .ToolCalls
532+ Expect (toolCalls ).ToNot (BeEmpty ())
533+ for _ , tc := range toolCalls {
534+ Expect (tc .Function .Name ).To (Equal (specificTool ))
535+ Expect (tc .ID ).NotTo (BeEmpty ())
536+ Expect (tc .Type ).To (Equal ("function" ))
537+ args := make (map [string ]string )
538+ err := json .Unmarshal ([]byte (tc .Function .Arguments ), & args )
539+ Expect (err ).NotTo (HaveOccurred ())
540+
541+ if tc .Function .Name == functionNameGetWeather {
542+ Expect (tc .Function .Arguments ).To (ContainSubstring ("location" ))
543+ } else {
544+ Expect (tc .Function .Arguments ).To (ContainSubstring ("city" ))
545+ Expect (tc .Function .Arguments ).To (ContainSubstring ("unit" ))
546+ Expect (args ["unit" ]).To (Or (Equal ("C" ), Equal ("F" )))
547+ }
548+ }
549+ },
550+ func (mode string , specificTool string ) string {
551+ return "mode: " + mode + ", specificTool: " + specificTool
552+ },
553+ // Call several times because the tools and arguments are chosen randomly
554+ Entry (nil , common .ModeRandom , functionNameGetWeather ),
555+ Entry (nil , common .ModeRandom , functionNameGetTemperature ),
556+ Entry (nil , common .ModeRandom , functionNameGetWeather ),
557+ Entry (nil , common .ModeRandom , functionNameGetTemperature ),
558+ )
559+
502560 DescribeTable ("check validator" ,
503561 func (mode string ) {
504562 ctx := context .TODO ()
@@ -778,7 +836,7 @@ var _ = Describe("Simulator for request with tools", func() {
778836 toolCalls := resp .Choices [0 ].Message .ToolCalls
779837 Expect (toolCalls ).To (HaveLen (1 ))
780838 tc := toolCalls [0 ]
781- Expect (tc .Function .Name ).To (Equal ("get_temperature" ))
839+ Expect (tc .Function .Name ).To (Equal (functionNameGetTemperature ))
782840 Expect (tc .ID ).NotTo (BeEmpty ())
783841 Expect (tc .Type ).To (Equal ("function" ))
784842 args := make (map [string ]string )
0 commit comments