diff --git a/internal/api/docs/openapi.yaml b/internal/api/docs/openapi.yaml index f2b3a999..b61aeac3 100644 --- a/internal/api/docs/openapi.yaml +++ b/internal/api/docs/openapi.yaml @@ -1147,6 +1147,15 @@ components: $ref: '#/components/schemas/ErrorResponse' description: Precondition Failed schemas: + AIModel: + properties: + description: + type: string + id: + type: string + name: + type: string + type: object AIModelItem: properties: brick_ids: @@ -1336,6 +1345,10 @@ components: type: string category: type: string + compatible_models: + items: + $ref: '#/components/schemas/AIModel' + type: array config_variables: items: $ref: '#/components/schemas/BrickConfigVariable' diff --git a/internal/e2e/client/client.gen.go b/internal/e2e/client/client.gen.go index f6094430..8db25bea 100644 --- a/internal/e2e/client/client.gen.go +++ b/internal/e2e/client/client.gen.go @@ -1,6 +1,6 @@ // Package client provides primitives to interact with the openapi HTTP API. // -// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.5.0 DO NOT EDIT. +// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.5.1 DO NOT EDIT. package client import ( @@ -41,6 +41,13 @@ const ( StarsDesc ListLibrariesParamsSort = "stars_desc" ) +// AIModel defines model for AIModel. +type AIModel struct { + Description *string `json:"description,omitempty"` + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` +} + // AIModelItem defines model for AIModelItem. type AIModelItem struct { BrickIds *[]string `json:"brick_ids"` @@ -150,13 +157,14 @@ type BrickDetailsResult struct { // BrickInstance defines model for BrickInstance. type BrickInstance struct { - Author *string `json:"author,omitempty"` - Category *string `json:"category,omitempty"` - ConfigVariables *[]BrickConfigVariable `json:"config_variables,omitempty"` - Id *string `json:"id,omitempty"` - Model *string `json:"model,omitempty"` - Name *string `json:"name,omitempty"` - Status *string `json:"status,omitempty"` + Author *string `json:"author,omitempty"` + Category *string `json:"category,omitempty"` + CompatibleModels *[]AIModel `json:"compatible_models,omitempty"` + ConfigVariables *[]BrickConfigVariable `json:"config_variables,omitempty"` + Id *string `json:"id,omitempty"` + Model *string `json:"model,omitempty"` + Name *string `json:"name,omitempty"` + Status *string `json:"status,omitempty"` // Variables Deprecated: use config_variables instead. This field is kept for backward compatibility. Variables *map[string]string `json:"variables,omitempty"` diff --git a/internal/e2e/daemon/instance_bricks_test.go b/internal/e2e/daemon/bricks_instance_test.go similarity index 94% rename from internal/e2e/daemon/instance_bricks_test.go rename to internal/e2e/daemon/bricks_instance_test.go index c210a9e6..dde5021d 100644 --- a/internal/e2e/daemon/instance_bricks_test.go +++ b/internal/e2e/daemon/bricks_instance_test.go @@ -51,6 +51,18 @@ var ( Value: f.Ptr("/models/ootb/ei/mobilenet-v2-224px.eim"), }, } + + expectedModelInfo = []client.AIModel{ + { + Id: f.Ptr("mobilenet-image-classification"), + Name: f.Ptr("General purpose image classification"), + Description: f.Ptr("General purpose image classification model based on MobileNetV2. This model is trained on the ImageNet dataset and can classify images into 1000 categories."), + }, + { + Id: f.Ptr("person-classification"), + Name: f.Ptr("Person classification"), + Description: f.Ptr("Person classification model based on WakeVision dataset. This model is trained to classify images into two categories: person and not-person."), + }} ) func setupTestApp(t *testing.T) (*client.CreateAppResp, *client.ClientWithResponses) { @@ -78,7 +90,6 @@ func setupTestApp(t *testing.T) (*client.CreateAppResp, *client.ClientWithRespon ) require.NoError(t, err) require.Equal(t, http.StatusOK, resp.StatusCode()) - return createResp, httpClient } @@ -135,6 +146,20 @@ func TestGetAppBrickInstanceById(t *testing.T) { require.NotEmpty(t, brickInstance.JSON200) require.Equal(t, ImageClassifactionBrickID, *brickInstance.JSON200.Id) require.Equal(t, expectedConfigVariables, (*brickInstance.JSON200.ConfigVariables)) + require.Nil(t, brickInstance.JSON200.CompatibleModels) + }) + + t.Run("GetAppBrickInstanceByBrickIDWithCompatibleModels_Success", func(t *testing.T) { + brickInstance, err := httpClient.GetAppBrickInstanceByBrickIDWithResponse( + t.Context(), + *createResp.JSON201.Id, + ImageClassifactionBrickID, + func(ctx context.Context, req *http.Request) error { return nil }) + require.NoError(t, err) + require.NotEmpty(t, brickInstance.JSON200) + require.Equal(t, ImageClassifactionBrickID, *brickInstance.JSON200.Id) + require.NotNil(t, brickInstance.JSON200.CompatibleModels) + require.Equal(t, expectedModelInfo, *(brickInstance.JSON200.CompatibleModels)) }) t.Run("GetAppBrickInstanceByBrickID_InvalidAppID_Fails", func(t *testing.T) { diff --git a/internal/orchestrator/bricks/bricks.go b/internal/orchestrator/bricks/bricks.go index e8dea9da..56ff741b 100644 --- a/internal/orchestrator/bricks/bricks.go +++ b/internal/orchestrator/bricks/bricks.go @@ -124,6 +124,13 @@ func (s *Service) AppBrickInstanceDetails(a *app.ArduinoApp, brickID string) (Br Variables: variables, ConfigVariables: configVariables, ModelID: modelID, + CompatibleModels: f.Map(s.modelsIndex.GetModelsByBrick(brick.ID), func(m modelsindex.AIModel) AIModel { + return AIModel{ + ID: m.ID, + Name: m.Name, + Description: m.ModuleDescription, + } + }), }, nil } diff --git a/internal/orchestrator/bricks/types.go b/internal/orchestrator/bricks/types.go index 868c563a..f505c9db 100644 --- a/internal/orchestrator/bricks/types.go +++ b/internal/orchestrator/bricks/types.go @@ -34,16 +34,22 @@ type AppBrickInstancesResult struct { } type BrickInstance struct { - ID string `json:"id"` - Name string `json:"name"` - Author string `json:"author"` - Category string `json:"category"` - Status string `json:"status"` - Variables map[string]string `json:"variables,omitempty" description:"Deprecated: use config_variables instead. This field is kept for backward compatibility."` - ConfigVariables []BrickConfigVariable `json:"config_variables,omitempty"` - ModelID string `json:"model,omitempty"` + ID string `json:"id"` + Name string `json:"name"` + Author string `json:"author"` + Category string `json:"category"` + Status string `json:"status"` + Variables map[string]string `json:"variables,omitempty" description:"Deprecated: use config_variables instead. This field is kept for backward compatibility."` + ConfigVariables []BrickConfigVariable `json:"config_variables,omitempty"` + ModelID string `json:"model,omitempty"` + CompatibleModels []AIModel `json:"compatible_models,omitempty"` } +type AIModel struct { + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` +} type BrickConfigVariable struct { Name string `json:"name"` Value string `json:"value"`