diff --git a/openai/assistant_resource_test.go b/openai/assistant_resource_test.go index faebeaf..e7b1f08 100644 --- a/openai/assistant_resource_test.go +++ b/openai/assistant_resource_test.go @@ -8,6 +8,48 @@ import ( "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) +func TestAccAssistantResource_tool_simple(t *testing.T) { + rName := acctest.RandomWithPrefix("openai_tf_test_") + assistantResourceName := "openai_assistant.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Create and Read testing + { + Config: testAccAssistantResourceConfig_tool_simple(rName, "test description"), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet(assistantResourceName, "id"), + resource.TestCheckResourceAttr(assistantResourceName, "name", rName), + resource.TestCheckResourceAttr(assistantResourceName, "description", "test description"), + resource.TestCheckResourceAttr(assistantResourceName, "model", "gpt-4"), + resource.TestCheckResourceAttr(assistantResourceName, "instructions", "You are a personal math tutor. When asked a question, write and run Python code to answer the question."), + ), + }, + // Update and Read testing + { + Config: testAccAssistantResourceConfig_tool_simple(rName, "test description updated"), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(assistantResourceName, "description", "test description updated"), + ), + }, + // ImportState testing + { + ResourceName: assistantResourceName, + ImportState: true, + ImportStateVerify: true, + // This is not normally necessary, but is here because this + // example code does not have an actual upstream service. + // Once the Read method is able to refresh information from + // the upstream service, this can be removed. + // ImportStateVerifyIgnore: []string{"wait"}, + }, + // Delete testing automatically occurs in TestCase + }, + }) +} + func TestAccAssistantResource_tool_code_interpreter(t *testing.T) { rName := acctest.RandomWithPrefix("openai_tf_test_") assistantResourceName := "openai_assistant.test" @@ -176,6 +218,17 @@ func TestAccAssistantResource_complex(t *testing.T) { }) } +func testAccAssistantResourceConfig_tool_simple(rName string, description string) string { + return fmt.Sprintf(` +resource openai_assistant test { + name = %[1]q + description = %[2]q + model = "gpt-4" + instructions = "You are a personal math tutor. When asked a question, write and run Python code to answer the question." +} +`, rName, description) +} + func testAccAssistantResourceConfig_tool_code_interpreter(filename string, rName string, description string) string { return fmt.Sprintf(` resource openai_file test { diff --git a/openai/models.go b/openai/models.go index fef9cdc..b6fe3db 100644 --- a/openai/models.go +++ b/openai/models.go @@ -238,31 +238,35 @@ func NewOpenAIAssistantResourceModel(ctx context.Context, assistant *openai.Assi model.Metadata, _ = types.MapValueFrom(ctx, types.StringType, assistant.MetaData) } - var tools = make([]OpenAIAssistantToolModel, len(assistant.Tools)) - for i, t := range assistant.Tools { - tool := OpenAIAssistantToolModel{ - Type: types.StringValue(t.Type), - } - - if t.Function != nil { - parameters, err := json.Marshal(t.Function.Parameters) - if err != nil { - return model, diags - } - f := OpenAIAssistantToolFunctionModel{ - Name: types.StringValue(t.Function.Name), - Parameters: types.StringValue(string(parameters)), + if len(assistant.Tools) == 0 { + model.Tools = types.ListNull(types.ObjectType{AttrTypes: OpenAIAssistantToolModel{}.AttrTypes()}) + } else { + var tools = make([]OpenAIAssistantToolModel, len(assistant.Tools)) + for i, t := range assistant.Tools { + tool := OpenAIAssistantToolModel{ + Type: types.StringValue(t.Type), } - if t.Function.Description != nil { - f.Description = types.StringPointerValue(t.Function.Description) + + if t.Function != nil { + parameters, err := json.Marshal(t.Function.Parameters) + if err != nil { + return model, diags + } + f := OpenAIAssistantToolFunctionModel{ + Name: types.StringValue(t.Function.Name), + Parameters: types.StringValue(string(parameters)), + } + if t.Function.Description != nil { + f.Description = types.StringPointerValue(t.Function.Description) + } + tool.Function = &f } - tool.Function = &f + tools[i] = tool + } + model.Tools, diags = types.ListValueFrom(ctx, types.ObjectType{AttrTypes: OpenAIAssistantToolModel{}.AttrTypes()}, tools) + if diags.HasError() { + return model, diags } - tools[i] = tool - } - model.Tools, diags = types.ListValueFrom(ctx, types.ObjectType{AttrTypes: OpenAIAssistantToolModel{}.AttrTypes()}, tools) - if diags.HasError() { - return model, diags } if assistant.ToolResources != nil && (assistant.ToolResources.CodeInterpreter != nil || assistant.ToolResources.FileSearch != nil) {