From 1fd6682ad24a5f0522527f324862c68e62e38531 Mon Sep 17 00:00:00 2001 From: Giulio Pilotto Date: Thu, 20 Nov 2025 15:48:05 +0100 Subject: [PATCH 01/17] brick - add require on list and details --- internal/orchestrator/bricks/bricks.go | 39 +++++++++++-------- internal/orchestrator/bricks/types.go | 15 ++++--- .../orchestrator/bricksindex/bricks_index.go | 1 + 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/internal/orchestrator/bricks/bricks.go b/internal/orchestrator/bricks/bricks.go index cc9128c7..430ba37f 100644 --- a/internal/orchestrator/bricks/bricks.go +++ b/internal/orchestrator/bricks/bricks.go @@ -58,12 +58,16 @@ func (s *Service) List() (BrickListResult, error) { res := BrickListResult{Bricks: make([]BrickListItem, len(s.bricksIndex.Bricks))} for i, brick := range s.bricksIndex.Bricks { res.Bricks[i] = BrickListItem{ - ID: brick.ID, - Name: brick.Name, - Author: "Arduino", // TODO: for now we only support our bricks - Description: brick.Description, - Category: brick.Category, - Status: "installed", + ID: brick.ID, + Name: brick.Name, + Author: "Arduino", // TODO: for now we only support our bricks + Description: brick.Description, + Category: brick.Category, + Status: "installed", + ModelRequired: brick.ModelRequired, + Models: f.Map(s.modelsIndex.GetModelsByBrick(brick.ID), func(m modelsindex.AIModel) string { + return m.ID + }), } } return res, nil @@ -198,17 +202,18 @@ func (s *Service) BricksDetails(id string, idProvider *app.IDProvider, return BrickDetailsResult{}, fmt.Errorf("unable to get used by apps: %w", err) } return BrickDetailsResult{ - ID: id, - Name: brick.Name, - Author: "Arduino", // TODO: for now we only support our bricks - Description: brick.Description, - Category: brick.Category, - Status: "installed", // For now every Arduino brick are installed - Variables: variables, - Readme: readme, - ApiDocsPath: apiDocsPath, - CodeExamples: codeExamples, - UsedByApps: usedByApps, + ID: id, + Name: brick.Name, + Author: "Arduino", // TODO: for now we only support our bricks + Description: brick.Description, + Category: brick.Category, + ModelRequired: brick.ModelRequired, + Status: "installed", // For now every Arduino brick are installed + Variables: variables, + Readme: readme, + ApiDocsPath: apiDocsPath, + CodeExamples: codeExamples, + UsedByApps: usedByApps, CompatibleModels: f.Map(s.modelsIndex.GetModelsByBrick(brick.ID), func(m modelsindex.AIModel) AIModel { return AIModel{ ID: m.ID, diff --git a/internal/orchestrator/bricks/types.go b/internal/orchestrator/bricks/types.go index 782ec2f2..0854fac7 100644 --- a/internal/orchestrator/bricks/types.go +++ b/internal/orchestrator/bricks/types.go @@ -20,12 +20,14 @@ type BrickListResult struct { } type BrickListItem struct { - ID string `json:"id"` - Name string `json:"name"` - Author string `json:"author"` - Description string `json:"description"` - Category string `json:"category"` - Status string `json:"status"` + ID string `json:"id"` + Name string `json:"name"` + Author string `json:"author"` + Description string `json:"description"` + Category string `json:"category"` + Status string `json:"status"` + ModelRequired bool `json:"model_required"` + Models []string `json:"models"` } type AppBrickInstancesResult struct { @@ -78,6 +80,7 @@ type BrickDetailsResult struct { Description string `json:"description"` Category string `json:"category"` Status string `json:"status"` + ModelRequired bool `json:"model_required"` Variables map[string]BrickVariable `json:"variables,omitempty"` Readme string `json:"readme"` ApiDocsPath string `json:"api_docs_path"` diff --git a/internal/orchestrator/bricksindex/bricks_index.go b/internal/orchestrator/bricksindex/bricks_index.go index 9e52f1c6..86c656eb 100644 --- a/internal/orchestrator/bricksindex/bricks_index.go +++ b/internal/orchestrator/bricksindex/bricks_index.go @@ -58,6 +58,7 @@ type Brick struct { RequireModel bool `yaml:"require_model"` Variables []BrickVariable `yaml:"variables,omitempty"` Ports []string `yaml:"ports,omitempty"` + ModelRequired bool `yaml:"model_required,omitempty"` ModelName string `yaml:"model_name,omitempty"` MountDevicesIntoContainer bool `yaml:"mount_devices_into_container,omitempty"` RequiredDevices []string `yaml:"required_devices,omitempty"` From d00e85a158c36ce06b1cf4449c0dd10b80e8fbe6 Mon Sep 17 00:00:00 2001 From: Giulio Pilotto Date: Thu, 20 Nov 2025 16:39:57 +0100 Subject: [PATCH 02/17] require_model for the app bricks --- internal/orchestrator/bricks/bricks.go | 1 + internal/orchestrator/bricks/types.go | 1 + internal/orchestrator/orchestrator.go | 8 +++++--- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/internal/orchestrator/bricks/bricks.go b/internal/orchestrator/bricks/bricks.go index 430ba37f..c5ab6586 100644 --- a/internal/orchestrator/bricks/bricks.go +++ b/internal/orchestrator/bricks/bricks.go @@ -89,6 +89,7 @@ func (s *Service) AppBrickInstancesList(a *app.ArduinoApp) (AppBrickInstancesRes Author: "Arduino", // TODO: for now we only support our bricks Category: brick.Category, Status: "installed", + ModelRequired: brick.ModelRequired, ModelID: brickInstance.Model, // TODO: in case is not set by the user, should we return the default model? Variables: variablesMap, // TODO: do we want to show also the default value of not explicitly set variables? ConfigVariables: configVariables, diff --git a/internal/orchestrator/bricks/types.go b/internal/orchestrator/bricks/types.go index 0854fac7..d30c2de9 100644 --- a/internal/orchestrator/bricks/types.go +++ b/internal/orchestrator/bricks/types.go @@ -42,6 +42,7 @@ type BrickInstance struct { 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"` + ModelRequired bool `json:"model_required,omitempty"` ModelID string `json:"model,omitempty"` CompatibleModels []AIModel `json:"compatible_models"` } diff --git a/internal/orchestrator/orchestrator.go b/internal/orchestrator/orchestrator.go index 1a61145c..585a4887 100644 --- a/internal/orchestrator/orchestrator.go +++ b/internal/orchestrator/orchestrator.go @@ -673,9 +673,10 @@ type AppDetailedInfo struct { } type AppDetailedBrick struct { - ID string `json:"id" required:"true"` - Name string `json:"name" required:"true"` - Category string `json:"category,omitempty"` + ID string `json:"id" required:"true"` + Name string `json:"name" required:"true"` + Category string `json:"category,omitempty"` + ModelRequired bool `json:"model_required,omitempty"` } func AppDetails( @@ -738,6 +739,7 @@ func AppDetails( } res.Name = bi.Name res.Category = bi.Category + res.ModelRequired = bi.ModelRequired return res }), }, nil From 2c898e9a89fb4733485d86c1b4b6d752c249e837 Mon Sep 17 00:00:00 2001 From: Giulio Pilotto Date: Thu, 20 Nov 2025 17:19:20 +0100 Subject: [PATCH 03/17] fixing yaml ser --- internal/orchestrator/bricks/bricks.go | 2 +- internal/orchestrator/bricks/types.go | 6 +++--- internal/orchestrator/bricksindex/bricks_index.go | 3 +-- internal/orchestrator/bricksindex/bricks_index_test.go | 2 +- internal/orchestrator/orchestrator.go | 2 +- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/internal/orchestrator/bricks/bricks.go b/internal/orchestrator/bricks/bricks.go index c5ab6586..957e1cbb 100644 --- a/internal/orchestrator/bricks/bricks.go +++ b/internal/orchestrator/bricks/bricks.go @@ -89,7 +89,7 @@ func (s *Service) AppBrickInstancesList(a *app.ArduinoApp) (AppBrickInstancesRes Author: "Arduino", // TODO: for now we only support our bricks Category: brick.Category, Status: "installed", - ModelRequired: brick.ModelRequired, + ModelRequired: brick.ModelRequired, // TODO: in case is not set by the user, should we return false? ModelID: brickInstance.Model, // TODO: in case is not set by the user, should we return the default model? Variables: variablesMap, // TODO: do we want to show also the default value of not explicitly set variables? ConfigVariables: configVariables, diff --git a/internal/orchestrator/bricks/types.go b/internal/orchestrator/bricks/types.go index d30c2de9..3290e72c 100644 --- a/internal/orchestrator/bricks/types.go +++ b/internal/orchestrator/bricks/types.go @@ -26,7 +26,7 @@ type BrickListItem struct { Description string `json:"description"` Category string `json:"category"` Status string `json:"status"` - ModelRequired bool `json:"model_required"` + ModelRequired bool `json:"require_model"` Models []string `json:"models"` } @@ -42,7 +42,7 @@ type BrickInstance struct { 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"` - ModelRequired bool `json:"model_required,omitempty"` + ModelRequired bool `json:"require_model,omitempty"` ModelID string `json:"model,omitempty"` CompatibleModels []AIModel `json:"compatible_models"` } @@ -81,7 +81,7 @@ type BrickDetailsResult struct { Description string `json:"description"` Category string `json:"category"` Status string `json:"status"` - ModelRequired bool `json:"model_required"` + ModelRequired bool `json:"require_model"` Variables map[string]BrickVariable `json:"variables,omitempty"` Readme string `json:"readme"` ApiDocsPath string `json:"api_docs_path"` diff --git a/internal/orchestrator/bricksindex/bricks_index.go b/internal/orchestrator/bricksindex/bricks_index.go index 86c656eb..f2138a52 100644 --- a/internal/orchestrator/bricksindex/bricks_index.go +++ b/internal/orchestrator/bricksindex/bricks_index.go @@ -55,10 +55,9 @@ type Brick struct { Category string `yaml:"category,omitempty"` RequiresDisplay string `yaml:"requires_display,omitempty"` RequireContainer bool `yaml:"require_container"` - RequireModel bool `yaml:"require_model"` Variables []BrickVariable `yaml:"variables,omitempty"` Ports []string `yaml:"ports,omitempty"` - ModelRequired bool `yaml:"model_required,omitempty"` + ModelRequired bool `yaml:"require_model,omitempty"` ModelName string `yaml:"model_name,omitempty"` MountDevicesIntoContainer bool `yaml:"mount_devices_into_container,omitempty"` RequiredDevices []string `yaml:"required_devices,omitempty"` diff --git a/internal/orchestrator/bricksindex/bricks_index_test.go b/internal/orchestrator/bricksindex/bricks_index_test.go index 8b02c8e0..0f11cbfb 100644 --- a/internal/orchestrator/bricksindex/bricks_index_test.go +++ b/internal/orchestrator/bricksindex/bricks_index_test.go @@ -37,7 +37,7 @@ func TestGenerateBricksIndexFromFile(t *testing.T) { require.True(t, found) require.Equal(t, "Image Classification", b.Name) require.Equal(t, "mobilenet-image-classification", b.ModelName) - require.True(t, b.RequireModel) + require.True(t, b.ModelRequired) require.Len(t, b.Variables, 2) require.Equal(t, "CUSTOM_MODEL_PATH", b.Variables[0].Name) require.Equal(t, "/opt/models/ei/", b.Variables[0].DefaultValue) diff --git a/internal/orchestrator/orchestrator.go b/internal/orchestrator/orchestrator.go index 585a4887..05bead26 100644 --- a/internal/orchestrator/orchestrator.go +++ b/internal/orchestrator/orchestrator.go @@ -676,7 +676,7 @@ type AppDetailedBrick struct { ID string `json:"id" required:"true"` Name string `json:"name" required:"true"` Category string `json:"category,omitempty"` - ModelRequired bool `json:"model_required,omitempty"` + ModelRequired bool `json:"require_model,omitempty"` } func AppDetails( From 834851ee8d8ceeef537d97ddbf399357be5f92d4 Mon Sep 17 00:00:00 2001 From: Giulio Pilotto Date: Thu, 20 Nov 2025 17:31:05 +0100 Subject: [PATCH 04/17] list app brick detalis --- internal/orchestrator/bricks/bricks.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/orchestrator/bricks/bricks.go b/internal/orchestrator/bricks/bricks.go index 957e1cbb..d2d8282a 100644 --- a/internal/orchestrator/bricks/bricks.go +++ b/internal/orchestrator/bricks/bricks.go @@ -123,6 +123,7 @@ func (s *Service) AppBrickInstanceDetails(a *app.ArduinoApp, brickID string) (Br Author: "Arduino", // TODO: for now we only support our bricks Category: brick.Category, Status: "installed", // For now every Arduino brick are installed + ModelRequired: brick.ModelRequired, Variables: variables, ConfigVariables: configVariables, ModelID: modelID, From af45937503f74563c941a276f669cd78b44fc5a8 Mon Sep 17 00:00:00 2001 From: Giulio Pilotto Date: Fri, 21 Nov 2025 12:46:47 +0100 Subject: [PATCH 05/17] add tests on reqmodel --- internal/api/docs/openapi.yaml | 8 +++++++ internal/e2e/client/client.gen.go | 23 +++++++++++-------- internal/e2e/daemon/app_test.go | 7 +++--- internal/e2e/daemon/brick_test.go | 1 + .../bricksindex/bricks_index_test.go | 2 +- 5 files changed, 28 insertions(+), 13 deletions(-) diff --git a/internal/api/docs/openapi.yaml b/internal/api/docs/openapi.yaml index f50969e6..f32c9a76 100644 --- a/internal/api/docs/openapi.yaml +++ b/internal/api/docs/openapi.yaml @@ -1204,6 +1204,8 @@ components: type: string name: type: string + require_model: + type: boolean required: - id - name @@ -1332,6 +1334,8 @@ components: type: string readme: type: string + require_model: + type: boolean status: type: string used_by_apps: @@ -1365,6 +1369,8 @@ components: type: string name: type: string + require_model: + type: boolean status: type: string variables: @@ -1386,6 +1392,8 @@ components: type: string name: type: string + require_model: + type: boolean status: type: string type: object diff --git a/internal/e2e/client/client.gen.go b/internal/e2e/client/client.gen.go index 1f3e6bbd..40d7b496 100644 --- a/internal/e2e/client/client.gen.go +++ b/internal/e2e/client/client.gen.go @@ -71,9 +71,10 @@ type AppBrickInstancesResult struct { // AppDetailedBrick defines model for AppDetailedBrick. type AppDetailedBrick struct { - Category *string `json:"category,omitempty"` - Id string `json:"id"` - Name string `json:"name"` + Category *string `json:"category,omitempty"` + Id string `json:"id"` + Name string `json:"name"` + RequireModel *bool `json:"require_model,omitempty"` } // AppDetailedInfo defines model for AppDetailedInfo. @@ -151,6 +152,7 @@ type BrickDetailsResult struct { Id *string `json:"id,omitempty"` Name *string `json:"name,omitempty"` Readme *string `json:"readme,omitempty"` + RequireModel *bool `json:"require_model,omitempty"` Status *string `json:"status,omitempty"` UsedByApps *[]AppReference `json:"used_by_apps"` Variables *map[string]BrickVariable `json:"variables,omitempty"` @@ -165,6 +167,7 @@ type BrickInstance struct { Id *string `json:"id,omitempty"` Model *string `json:"model,omitempty"` Name *string `json:"name,omitempty"` + RequireModel *bool `json:"require_model,omitempty"` Status *string `json:"status,omitempty"` // Variables Deprecated: use config_variables instead. This field is kept for backward compatibility. @@ -173,12 +176,14 @@ type BrickInstance struct { // BrickListItem defines model for BrickListItem. type BrickListItem struct { - Author *string `json:"author,omitempty"` - Category *string `json:"category,omitempty"` - Description *string `json:"description,omitempty"` - Id *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` - Status *string `json:"status,omitempty"` + Author *string `json:"author,omitempty"` + Category *string `json:"category,omitempty"` + Description *string `json:"description,omitempty"` + Id *string `json:"id,omitempty"` + Models *[]string `json:"models"` + Name *string `json:"name,omitempty"` + RequireModel *bool `json:"require_model,omitempty"` + Status *string `json:"status,omitempty"` } // BrickListResult defines model for BrickListResult. diff --git a/internal/e2e/daemon/app_test.go b/internal/e2e/daemon/app_test.go index 1de8ff64..b62b882b 100644 --- a/internal/e2e/daemon/app_test.go +++ b/internal/e2e/daemon/app_test.go @@ -783,9 +783,10 @@ func TestAppDetails(t *testing.T) { require.Len(t, *detailsResp.JSON200.Bricks, 1) require.Equal(t, client.AppDetailedBrick{ - Id: ImageClassifactionBrickID, - Name: "Image Classification", - Category: f.Ptr("video"), + Id: ImageClassifactionBrickID, + Name: "Image Classification", + Category: f.Ptr("video"), + RequireModel: f.Ptr(true), }, (*detailsResp.JSON200.Bricks)[0], ) diff --git a/internal/e2e/daemon/brick_test.go b/internal/e2e/daemon/brick_test.go index 02736884..4e30db25 100644 --- a/internal/e2e/daemon/brick_test.go +++ b/internal/e2e/daemon/brick_test.go @@ -83,6 +83,7 @@ func TestBricksList(t *testing.T) { require.Equal(t, bIdx.Description, *brick.Description) require.Equal(t, "Arduino", *brick.Author) require.Equal(t, "installed", *brick.Status) + require.Equal(t, bIdx.ModelRequired, *brick.RequireModel) } } diff --git a/internal/orchestrator/bricksindex/bricks_index_test.go b/internal/orchestrator/bricksindex/bricks_index_test.go index 0f11cbfb..8b02c8e0 100644 --- a/internal/orchestrator/bricksindex/bricks_index_test.go +++ b/internal/orchestrator/bricksindex/bricks_index_test.go @@ -37,7 +37,7 @@ func TestGenerateBricksIndexFromFile(t *testing.T) { require.True(t, found) require.Equal(t, "Image Classification", b.Name) require.Equal(t, "mobilenet-image-classification", b.ModelName) - require.True(t, b.ModelRequired) + require.True(t, b.RequireModel) require.Len(t, b.Variables, 2) require.Equal(t, "CUSTOM_MODEL_PATH", b.Variables[0].Name) require.Equal(t, "/opt/models/ei/", b.Variables[0].DefaultValue) From 60a2f797d49c1fbdd4a00ef7a1ed36fa88e2725c Mon Sep 17 00:00:00 2001 From: Giulio Pilotto Date: Fri, 21 Nov 2025 15:20:22 +0100 Subject: [PATCH 06/17] rename to RequireModel --- internal/e2e/daemon/brick_test.go | 2 +- internal/orchestrator/bricks/bricks.go | 42 +++++++++---------- internal/orchestrator/bricks/types.go | 20 ++++----- .../orchestrator/bricksindex/bricks_index.go | 2 +- internal/orchestrator/orchestrator.go | 10 ++--- 5 files changed, 38 insertions(+), 38 deletions(-) diff --git a/internal/e2e/daemon/brick_test.go b/internal/e2e/daemon/brick_test.go index 4e30db25..5d709bb3 100644 --- a/internal/e2e/daemon/brick_test.go +++ b/internal/e2e/daemon/brick_test.go @@ -83,7 +83,7 @@ func TestBricksList(t *testing.T) { require.Equal(t, bIdx.Description, *brick.Description) require.Equal(t, "Arduino", *brick.Author) require.Equal(t, "installed", *brick.Status) - require.Equal(t, bIdx.ModelRequired, *brick.RequireModel) + require.Equal(t, bIdx.RequireModel, *brick.RequireModel) } } diff --git a/internal/orchestrator/bricks/bricks.go b/internal/orchestrator/bricks/bricks.go index d2d8282a..da6cd739 100644 --- a/internal/orchestrator/bricks/bricks.go +++ b/internal/orchestrator/bricks/bricks.go @@ -58,13 +58,13 @@ func (s *Service) List() (BrickListResult, error) { res := BrickListResult{Bricks: make([]BrickListItem, len(s.bricksIndex.Bricks))} for i, brick := range s.bricksIndex.Bricks { res.Bricks[i] = BrickListItem{ - ID: brick.ID, - Name: brick.Name, - Author: "Arduino", // TODO: for now we only support our bricks - Description: brick.Description, - Category: brick.Category, - Status: "installed", - ModelRequired: brick.ModelRequired, + ID: brick.ID, + Name: brick.Name, + Author: "Arduino", // TODO: for now we only support our bricks + Description: brick.Description, + Category: brick.Category, + Status: "installed", + RequireModel: brick.RequireModel, Models: f.Map(s.modelsIndex.GetModelsByBrick(brick.ID), func(m modelsindex.AIModel) string { return m.ID }), @@ -89,7 +89,7 @@ func (s *Service) AppBrickInstancesList(a *app.ArduinoApp) (AppBrickInstancesRes Author: "Arduino", // TODO: for now we only support our bricks Category: brick.Category, Status: "installed", - ModelRequired: brick.ModelRequired, // TODO: in case is not set by the user, should we return false? + RequireModel: brick.RequireModel, ModelID: brickInstance.Model, // TODO: in case is not set by the user, should we return the default model? Variables: variablesMap, // TODO: do we want to show also the default value of not explicitly set variables? ConfigVariables: configVariables, @@ -123,7 +123,7 @@ func (s *Service) AppBrickInstanceDetails(a *app.ArduinoApp, brickID string) (Br Author: "Arduino", // TODO: for now we only support our bricks Category: brick.Category, Status: "installed", // For now every Arduino brick are installed - ModelRequired: brick.ModelRequired, + RequireModel: brick.RequireModel, Variables: variables, ConfigVariables: configVariables, ModelID: modelID, @@ -204,18 +204,18 @@ func (s *Service) BricksDetails(id string, idProvider *app.IDProvider, return BrickDetailsResult{}, fmt.Errorf("unable to get used by apps: %w", err) } return BrickDetailsResult{ - ID: id, - Name: brick.Name, - Author: "Arduino", // TODO: for now we only support our bricks - Description: brick.Description, - Category: brick.Category, - ModelRequired: brick.ModelRequired, - Status: "installed", // For now every Arduino brick are installed - Variables: variables, - Readme: readme, - ApiDocsPath: apiDocsPath, - CodeExamples: codeExamples, - UsedByApps: usedByApps, + ID: id, + Name: brick.Name, + Author: "Arduino", // TODO: for now we only support our bricks + Description: brick.Description, + Category: brick.Category, + RequireModel: brick.RequireModel, + Status: "installed", // For now every Arduino brick are installed + Variables: variables, + Readme: readme, + ApiDocsPath: apiDocsPath, + CodeExamples: codeExamples, + UsedByApps: usedByApps, CompatibleModels: f.Map(s.modelsIndex.GetModelsByBrick(brick.ID), func(m modelsindex.AIModel) AIModel { return AIModel{ ID: m.ID, diff --git a/internal/orchestrator/bricks/types.go b/internal/orchestrator/bricks/types.go index 3290e72c..3aa0afe3 100644 --- a/internal/orchestrator/bricks/types.go +++ b/internal/orchestrator/bricks/types.go @@ -20,14 +20,14 @@ type BrickListResult struct { } type BrickListItem struct { - ID string `json:"id"` - Name string `json:"name"` - Author string `json:"author"` - Description string `json:"description"` - Category string `json:"category"` - Status string `json:"status"` - ModelRequired bool `json:"require_model"` - Models []string `json:"models"` + ID string `json:"id"` + Name string `json:"name"` + Author string `json:"author"` + Description string `json:"description"` + Category string `json:"category"` + Status string `json:"status"` + RequireModel bool `json:"require_model"` + Models []string `json:"models"` } type AppBrickInstancesResult struct { @@ -42,7 +42,7 @@ type BrickInstance struct { 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"` - ModelRequired bool `json:"require_model,omitempty"` + RequireModel bool `json:"require_model"` ModelID string `json:"model,omitempty"` CompatibleModels []AIModel `json:"compatible_models"` } @@ -81,7 +81,7 @@ type BrickDetailsResult struct { Description string `json:"description"` Category string `json:"category"` Status string `json:"status"` - ModelRequired bool `json:"require_model"` + RequireModel bool `json:"require_model"` Variables map[string]BrickVariable `json:"variables,omitempty"` Readme string `json:"readme"` ApiDocsPath string `json:"api_docs_path"` diff --git a/internal/orchestrator/bricksindex/bricks_index.go b/internal/orchestrator/bricksindex/bricks_index.go index f2138a52..a8d39c8c 100644 --- a/internal/orchestrator/bricksindex/bricks_index.go +++ b/internal/orchestrator/bricksindex/bricks_index.go @@ -57,7 +57,7 @@ type Brick struct { RequireContainer bool `yaml:"require_container"` Variables []BrickVariable `yaml:"variables,omitempty"` Ports []string `yaml:"ports,omitempty"` - ModelRequired bool `yaml:"require_model,omitempty"` + RequireModel bool `yaml:"require_model"` ModelName string `yaml:"model_name,omitempty"` MountDevicesIntoContainer bool `yaml:"mount_devices_into_container,omitempty"` RequiredDevices []string `yaml:"required_devices,omitempty"` diff --git a/internal/orchestrator/orchestrator.go b/internal/orchestrator/orchestrator.go index 05bead26..74851180 100644 --- a/internal/orchestrator/orchestrator.go +++ b/internal/orchestrator/orchestrator.go @@ -673,10 +673,10 @@ type AppDetailedInfo struct { } type AppDetailedBrick struct { - ID string `json:"id" required:"true"` - Name string `json:"name" required:"true"` - Category string `json:"category,omitempty"` - ModelRequired bool `json:"require_model,omitempty"` + ID string `json:"id" required:"true"` + Name string `json:"name" required:"true"` + Category string `json:"category,omitempty"` + RequireModel bool `json:"require_model"` } func AppDetails( @@ -739,7 +739,7 @@ func AppDetails( } res.Name = bi.Name res.Category = bi.Category - res.ModelRequired = bi.ModelRequired + res.RequireModel = bi.RequireModel return res }), }, nil From 294ddf73a9a150e23000314a63c387322520d633 Mon Sep 17 00:00:00 2001 From: Giulio Pilotto Date: Tue, 25 Nov 2025 15:06:07 +0100 Subject: [PATCH 07/17] TestBricksList test --- internal/orchestrator/bricks/bricks_test.go | 13 ------------ .../bricks/testdata/bricks-list.yaml | 20 +++++++++++++++++++ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/internal/orchestrator/bricks/bricks_test.go b/internal/orchestrator/bricks/bricks_test.go index 4fee6fde..42953a86 100644 --- a/internal/orchestrator/bricks/bricks_test.go +++ b/internal/orchestrator/bricks/bricks_test.go @@ -252,19 +252,6 @@ func TestGetBrickInstanceVariableDetails(t *testing.T) { expectedConfigVariables []BrickConfigVariable expectedVariableMap map[string]string }{ - { - name: "variable is present in the map", - brick: &bricksindex.Brick{ - Variables: []bricksindex.BrickVariable{ - {Name: "VAR1", Description: "desc"}, - }, - }, - userVariables: map[string]string{"VAR1": "value1"}, - expectedConfigVariables: []BrickConfigVariable{ - {Name: "VAR1", Value: "value1", Description: "desc", Required: true}, - }, - expectedVariableMap: map[string]string{"VAR1": "value1"}, - }, { name: "variable not present in the map", brick: &bricksindex.Brick{ diff --git a/internal/orchestrator/bricks/testdata/bricks-list.yaml b/internal/orchestrator/bricks/testdata/bricks-list.yaml index 8e3114d6..e730639e 100644 --- a/internal/orchestrator/bricks/testdata/bricks-list.yaml +++ b/internal/orchestrator/bricks/testdata/bricks-list.yaml @@ -23,3 +23,23 @@ bricks: mount_devices_into_container: false ports: [] category: storage +- id: arduino:image_classification + name: Image Classification + description: "Brick for image classification using a pre-trained model. It processes\ + \ images and returns the predicted class label and confidence score.\nBrick is\ + \ designed to work with pre-trained models provided by framework or with custom\ + \ image classification models trained on Edge Impulse platform. \n" + require_container: true + require_model: true + require_devices: false + mount_devices_into_container: false + ports: [] + category: video + model_name: mobilenet-image-classification + variables: + - name: CUSTOM_MODEL_PATH + default_value: /home/arduino/.arduino-bricks/ei-models + description: path to the custom model directory + - name: EI_CLASSIFICATION_MODEL + default_value: /models/ootb/ei/mobilenet-v2-224px.eim + description: path to the model file From e92a2be3c543d7c8bc7d6b563efedc007b9cc624 Mon Sep 17 00:00:00 2001 From: Giulio Pilotto Date: Tue, 25 Nov 2025 15:44:55 +0100 Subject: [PATCH 08/17] TestAppBrickInstanceDetails --- internal/orchestrator/bricks/bricks_test.go | 40 +++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/internal/orchestrator/bricks/bricks_test.go b/internal/orchestrator/bricks/bricks_test.go index 42953a86..550907ad 100644 --- a/internal/orchestrator/bricks/bricks_test.go +++ b/internal/orchestrator/bricks/bricks_test.go @@ -626,3 +626,43 @@ func TestAppBrickInstanceModelsDetails(t *testing.T) { }) } } + +func TestAppBrickInstanceDetails(t *testing.T) { + bricksIndex, err := bricksindex.GenerateBricksIndexFromFile(paths.New("testdata")) + require.Nil(t, err) + brickService := NewService(nil, bricksIndex, nil) + tempDirectory := t.TempDir() + + app := app.ArduinoApp{ + Name: "TestApp", + Descriptor: app.AppDescriptor{ + Bricks: []app.Brick{ + { + ID: "arduino:image_classification", + }, + }, + }, + FullPath: paths.New(tempDirectory), + } + configVariables, _ := brickService.AppBrickInstanceDetails(&app, bricksIndex.Bricks[2].ID) + + expectedConfigVariables := BrickInstance{ + Name: "Image Classification", + ID: "arduino:image_classification", + Author: "Arduino", + Category: "video", + Status: "installed", + Variables: map[string]string{ + "CUSTOM_MODEL_PATH": "/home/arduino/.arduino-bricks/ei-models", + "EI_CLASSIFICATION_MODEL": "/models/ootb/ei/mobilenet-v2-224px.eim", + }, + ConfigVariables: []BrickConfigVariable{ + {Name: "CUSTOM_MODEL_PATH", Value: "/home/arduino/.arduino-bricks/ei-models", Description: "path to the custom model directory", Required: false}, + {Name: "EI_CLASSIFICATION_MODEL", Value: "/models/ootb/ei/mobilenet-v2-224px.eim", Description: "path to the model file", Required: false}, + }, + RequireModel: true, + ModelID: "mobilenet-image-classification", + } + + require.Equal(t, expectedConfigVariables, configVariables) +} From 4850345206d2f779f1673d069368805da0696191 Mon Sep 17 00:00:00 2001 From: Giulio Pilotto Date: Tue, 25 Nov 2025 15:47:13 +0100 Subject: [PATCH 09/17] fix --- internal/orchestrator/bricks/bricks_test.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/internal/orchestrator/bricks/bricks_test.go b/internal/orchestrator/bricks/bricks_test.go index 550907ad..0649aa4c 100644 --- a/internal/orchestrator/bricks/bricks_test.go +++ b/internal/orchestrator/bricks/bricks_test.go @@ -252,6 +252,19 @@ func TestGetBrickInstanceVariableDetails(t *testing.T) { expectedConfigVariables []BrickConfigVariable expectedVariableMap map[string]string }{ + { + name: "variable is present in the map", + brick: &bricksindex.Brick{ + Variables: []bricksindex.BrickVariable{ + {Name: "VAR1", Description: "desc"}, + }, + }, + userVariables: map[string]string{"VAR1": "value1"}, + expectedConfigVariables: []BrickConfigVariable{ + {Name: "VAR1", Value: "value1", Description: "desc", Required: true}, + }, + expectedVariableMap: map[string]string{"VAR1": "value1"}, + }, { name: "variable not present in the map", brick: &bricksindex.Brick{ From c44f649e299fccadbcc091eaab1a4004fbaa398e Mon Sep 17 00:00:00 2001 From: Giulio Pilotto Date: Wed, 26 Nov 2025 12:36:40 +0100 Subject: [PATCH 10/17] update tests --- internal/api/docs/openapi.yaml | 5 +++ internal/orchestrator/bricks/bricks_test.go | 40 ------------------- .../bricks/testdata/bricks-list.yaml | 2 + .../bricksindex/bricks_index_test.go | 39 ++++++++++++------ .../bricksindex/testdata/bricks-list.yaml | 7 +++- 5 files changed, 39 insertions(+), 54 deletions(-) diff --git a/internal/api/docs/openapi.yaml b/internal/api/docs/openapi.yaml index f32c9a76..1419b449 100644 --- a/internal/api/docs/openapi.yaml +++ b/internal/api/docs/openapi.yaml @@ -1390,6 +1390,11 @@ components: type: string id: type: string + models: + items: + type: string + nullable: true + type: array name: type: string require_model: diff --git a/internal/orchestrator/bricks/bricks_test.go b/internal/orchestrator/bricks/bricks_test.go index 0649aa4c..4fee6fde 100644 --- a/internal/orchestrator/bricks/bricks_test.go +++ b/internal/orchestrator/bricks/bricks_test.go @@ -639,43 +639,3 @@ func TestAppBrickInstanceModelsDetails(t *testing.T) { }) } } - -func TestAppBrickInstanceDetails(t *testing.T) { - bricksIndex, err := bricksindex.GenerateBricksIndexFromFile(paths.New("testdata")) - require.Nil(t, err) - brickService := NewService(nil, bricksIndex, nil) - tempDirectory := t.TempDir() - - app := app.ArduinoApp{ - Name: "TestApp", - Descriptor: app.AppDescriptor{ - Bricks: []app.Brick{ - { - ID: "arduino:image_classification", - }, - }, - }, - FullPath: paths.New(tempDirectory), - } - configVariables, _ := brickService.AppBrickInstanceDetails(&app, bricksIndex.Bricks[2].ID) - - expectedConfigVariables := BrickInstance{ - Name: "Image Classification", - ID: "arduino:image_classification", - Author: "Arduino", - Category: "video", - Status: "installed", - Variables: map[string]string{ - "CUSTOM_MODEL_PATH": "/home/arduino/.arduino-bricks/ei-models", - "EI_CLASSIFICATION_MODEL": "/models/ootb/ei/mobilenet-v2-224px.eim", - }, - ConfigVariables: []BrickConfigVariable{ - {Name: "CUSTOM_MODEL_PATH", Value: "/home/arduino/.arduino-bricks/ei-models", Description: "path to the custom model directory", Required: false}, - {Name: "EI_CLASSIFICATION_MODEL", Value: "/models/ootb/ei/mobilenet-v2-224px.eim", Description: "path to the model file", Required: false}, - }, - RequireModel: true, - ModelID: "mobilenet-image-classification", - } - - require.Equal(t, expectedConfigVariables, configVariables) -} diff --git a/internal/orchestrator/bricks/testdata/bricks-list.yaml b/internal/orchestrator/bricks/testdata/bricks-list.yaml index e730639e..91660089 100644 --- a/internal/orchestrator/bricks/testdata/bricks-list.yaml +++ b/internal/orchestrator/bricks/testdata/bricks-list.yaml @@ -43,3 +43,5 @@ bricks: - name: EI_CLASSIFICATION_MODEL default_value: /models/ootb/ei/mobilenet-v2-224px.eim description: path to the model file + + diff --git a/internal/orchestrator/bricksindex/bricks_index_test.go b/internal/orchestrator/bricksindex/bricks_index_test.go index 8b02c8e0..325a1c76 100644 --- a/internal/orchestrator/bricksindex/bricks_index_test.go +++ b/internal/orchestrator/bricksindex/bricks_index_test.go @@ -33,20 +33,33 @@ func TestGenerateBricksIndexFromFile(t *testing.T) { require.Equal(t, []string{"7000"}, b.Ports) // Check if variables are correctly set - b, found = index.FindBrickByID("arduino:image_classification") + bWebUI, found := index.FindBrickByID("arduino:web_ui") require.True(t, found) - require.Equal(t, "Image Classification", b.Name) - require.Equal(t, "mobilenet-image-classification", b.ModelName) - require.True(t, b.RequireModel) - require.Len(t, b.Variables, 2) - require.Equal(t, "CUSTOM_MODEL_PATH", b.Variables[0].Name) - require.Equal(t, "/opt/models/ei/", b.Variables[0].DefaultValue) - require.Equal(t, "path to the custom model directory", b.Variables[0].Description) - require.Equal(t, "EI_CLASSIFICATION_MODEL", b.Variables[1].Name) - require.Equal(t, "/models/ootb/ei/mobilenet-v2-224px.eim", b.Variables[1].DefaultValue) - require.Equal(t, "path to the model file", b.Variables[1].Description) - require.False(t, b.Variables[0].IsRequired()) - require.False(t, b.Variables[1].IsRequired()) + require.Equal(t, []string{"7000"}, bWebUI.Ports) + + // Check if variables are correctly set + bWebUI, found = index.FindBrickByID("arduino:image_classification") + require.True(t, found) + require.Equal(t, "Image Classification", bWebUI.Name) + require.Equal(t, "mobilenet-image-classification", bWebUI.ModelName) + require.True(t, bWebUI.RequireModel) + require.Len(t, bWebUI.Variables, 2) + require.Equal(t, "CUSTOM_MODEL_PATH", bWebUI.Variables[0].Name) + require.Equal(t, "/opt/models/ei/", bWebUI.Variables[0].DefaultValue) + require.Equal(t, "path to the custom model directory", bWebUI.Variables[0].Description) + require.Equal(t, "EI_CLASSIFICATION_MODEL", bWebUI.Variables[1].Name) + require.Equal(t, "/models/ootb/ei/mobilenet-v2-224px.eim", bWebUI.Variables[1].DefaultValue) + require.Equal(t, "path to the model file", bWebUI.Variables[1].Description) + require.False(t, bWebUI.Variables[0].IsRequired()) + require.False(t, bWebUI.Variables[1].IsRequired()) + + bDb, found := index.FindBrickByID("arduino:dbstorage_tsstore") + require.True(t, found) + require.False(t, bDb.RequireModel) + + bNoRequireModel, found := index.FindBrickByID("arduino:missing-model-require") + require.True(t, found) + require.False(t, bNoRequireModel.RequireModel) } func TestBricksIndexYAMLFormats(t *testing.T) { diff --git a/internal/orchestrator/bricksindex/testdata/bricks-list.yaml b/internal/orchestrator/bricksindex/testdata/bricks-list.yaml index 0bd036f8..6794e27b 100644 --- a/internal/orchestrator/bricksindex/testdata/bricks-list.yaml +++ b/internal/orchestrator/bricksindex/testdata/bricks-list.yaml @@ -130,4 +130,9 @@ bricks: description: path to the custom model directory - name: EI_V_ANOMALY_DETECTION_MODEL default_value: /models/ootb/ei/concrete-crack-anomaly-detection.eim - description: path to the model file \ No newline at end of file + description: path to the model file +- id: arduino:missing-model-require + name: Camera Scanner + description: Scans a camera for barcodes and QR codes + require_container: false + ports: [] From f51170413bfca47d1694a5ab12a63bb2f2e44eb1 Mon Sep 17 00:00:00 2001 From: Giulio Pilotto Date: Wed, 26 Nov 2025 12:48:37 +0100 Subject: [PATCH 11/17] add RequireModel to test --- internal/orchestrator/bricks/bricks_test.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/internal/orchestrator/bricks/bricks_test.go b/internal/orchestrator/bricks/bricks_test.go index 4fee6fde..0077a5b2 100644 --- a/internal/orchestrator/bricks/bricks_test.go +++ b/internal/orchestrator/bricks/bricks_test.go @@ -503,12 +503,14 @@ func TestAppBrickInstanceModelsDetails(t *testing.T) { {Name: "EI_OBJ_DETECTION_MODEL", DefaultValue: "default_path", Description: "path to the model file"}, {Name: "CUSTOM_MODEL_PATH", DefaultValue: "/home/arduino/.arduino-bricks/ei-models", Description: "path to the custom model directory"}, }, + RequireModel: true, }, { - ID: "arduino:weather_forecast", - Name: "Weather Forecast", - Category: "miscellaneous", - ModelName: "", + ID: "arduino:weather_forecast", + Name: "Weather Forecast", + Category: "miscellaneous", + ModelName: "", + RequireModel: false, }, }, } @@ -577,6 +579,7 @@ func TestAppBrickInstanceModelsDetails(t *testing.T) { require.Equal(t, "installed", res.Status) require.Empty(t, res.ModelID) require.Empty(t, res.CompatibleModels) + require.False(t, res.RequireModel) }, }, { @@ -597,6 +600,7 @@ func TestAppBrickInstanceModelsDetails(t *testing.T) { require.Len(t, res.CompatibleModels, 2) require.Equal(t, "yolox-object-detection", res.CompatibleModels[0].ID) require.Equal(t, "face-detection", res.CompatibleModels[1].ID) + require.True(t, res.RequireModel) }, }, { @@ -618,6 +622,7 @@ func TestAppBrickInstanceModelsDetails(t *testing.T) { require.Len(t, res.CompatibleModels, 2) require.Equal(t, "yolox-object-detection", res.CompatibleModels[0].ID) require.Equal(t, "face-detection", res.CompatibleModels[1].ID) + require.True(t, res.RequireModel) }, }, } From 20bc5e02ee74f2f566930528c0210e51fd4bd28b Mon Sep 17 00:00:00 2001 From: Giulio Pilotto Date: Wed, 26 Nov 2025 13:09:38 +0100 Subject: [PATCH 12/17] add test IC --- .../bricksindex/bricks_index_test.go | 34 +++++++++---------- .../bricksindex/testdata/bricks-list.yaml | 4 +++ 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/internal/orchestrator/bricksindex/bricks_index_test.go b/internal/orchestrator/bricksindex/bricks_index_test.go index 325a1c76..b8bf7c0a 100644 --- a/internal/orchestrator/bricksindex/bricks_index_test.go +++ b/internal/orchestrator/bricksindex/bricks_index_test.go @@ -28,30 +28,28 @@ func TestGenerateBricksIndexFromFile(t *testing.T) { require.NoError(t, err) // Check if ports are correctly set - b, found := index.FindBrickByID("arduino:web_ui") - require.True(t, found) - require.Equal(t, []string{"7000"}, b.Ports) - - // Check if variables are correctly set bWebUI, found := index.FindBrickByID("arduino:web_ui") require.True(t, found) require.Equal(t, []string{"7000"}, bWebUI.Ports) // Check if variables are correctly set - bWebUI, found = index.FindBrickByID("arduino:image_classification") + bIC, found := index.FindBrickByID("arduino:image_classification") + require.True(t, found) + require.Equal(t, "Image Classification", bIC.Name) + require.Equal(t, "mobilenet-image-classification", bIC.ModelName) + require.Len(t, bIC.Variables, 2) + require.Equal(t, "CUSTOM_MODEL_PATH", bIC.Variables[0].Name) + require.Equal(t, "/opt/models/ei/", bIC.Variables[0].DefaultValue) + require.Equal(t, "path to the custom model directory", bIC.Variables[0].Description) + require.Equal(t, "EI_CLASSIFICATION_MODEL", bIC.Variables[1].Name) + require.Equal(t, "/models/ootb/ei/mobilenet-v2-224px.eim", bIC.Variables[1].DefaultValue) + require.Equal(t, "path to the model file", bIC.Variables[1].Description) + require.False(t, bIC.Variables[0].IsRequired()) + require.False(t, bIC.Variables[1].IsRequired()) + + bRequireModel, found := index.FindBrickByID("arduino:model_required") require.True(t, found) - require.Equal(t, "Image Classification", bWebUI.Name) - require.Equal(t, "mobilenet-image-classification", bWebUI.ModelName) - require.True(t, bWebUI.RequireModel) - require.Len(t, bWebUI.Variables, 2) - require.Equal(t, "CUSTOM_MODEL_PATH", bWebUI.Variables[0].Name) - require.Equal(t, "/opt/models/ei/", bWebUI.Variables[0].DefaultValue) - require.Equal(t, "path to the custom model directory", bWebUI.Variables[0].Description) - require.Equal(t, "EI_CLASSIFICATION_MODEL", bWebUI.Variables[1].Name) - require.Equal(t, "/models/ootb/ei/mobilenet-v2-224px.eim", bWebUI.Variables[1].DefaultValue) - require.Equal(t, "path to the model file", bWebUI.Variables[1].Description) - require.False(t, bWebUI.Variables[0].IsRequired()) - require.False(t, bWebUI.Variables[1].IsRequired()) + require.True(t, bRequireModel.RequireModel) bDb, found := index.FindBrickByID("arduino:dbstorage_tsstore") require.True(t, found) diff --git a/internal/orchestrator/bricksindex/testdata/bricks-list.yaml b/internal/orchestrator/bricksindex/testdata/bricks-list.yaml index 6794e27b..344bef7e 100644 --- a/internal/orchestrator/bricksindex/testdata/bricks-list.yaml +++ b/internal/orchestrator/bricksindex/testdata/bricks-list.yaml @@ -16,6 +16,10 @@ bricks: - name: EI_CLASSIFICATION_MODEL default_value: /models/ootb/ei/mobilenet-v2-224px.eim description: path to the model file +- id: arduino:model_required + name: Model Required Brick + description: A brick that requires a model + require_model: true - id: arduino:camera_scanner name: Camera Scanner description: Scans a camera for barcodes and QR codes From 8073e3c271b9f23f19508bde569371f22c958e6f Mon Sep 17 00:00:00 2001 From: Giulio Pilotto Date: Wed, 26 Nov 2025 13:18:02 +0100 Subject: [PATCH 13/17] remove models --- internal/api/docs/openapi.yaml | 5 ----- internal/e2e/client/client.gen.go | 15 +++++++-------- internal/orchestrator/bricks/bricks.go | 3 --- internal/orchestrator/bricks/types.go | 15 +++++++-------- 4 files changed, 14 insertions(+), 24 deletions(-) diff --git a/internal/api/docs/openapi.yaml b/internal/api/docs/openapi.yaml index 1419b449..f32c9a76 100644 --- a/internal/api/docs/openapi.yaml +++ b/internal/api/docs/openapi.yaml @@ -1390,11 +1390,6 @@ components: type: string id: type: string - models: - items: - type: string - nullable: true - type: array name: type: string require_model: diff --git a/internal/e2e/client/client.gen.go b/internal/e2e/client/client.gen.go index 40d7b496..496680c9 100644 --- a/internal/e2e/client/client.gen.go +++ b/internal/e2e/client/client.gen.go @@ -176,14 +176,13 @@ type BrickInstance struct { // BrickListItem defines model for BrickListItem. type BrickListItem struct { - Author *string `json:"author,omitempty"` - Category *string `json:"category,omitempty"` - Description *string `json:"description,omitempty"` - Id *string `json:"id,omitempty"` - Models *[]string `json:"models"` - Name *string `json:"name,omitempty"` - RequireModel *bool `json:"require_model,omitempty"` - Status *string `json:"status,omitempty"` + Author *string `json:"author,omitempty"` + Category *string `json:"category,omitempty"` + Description *string `json:"description,omitempty"` + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + RequireModel *bool `json:"require_model,omitempty"` + Status *string `json:"status,omitempty"` } // BrickListResult defines model for BrickListResult. diff --git a/internal/orchestrator/bricks/bricks.go b/internal/orchestrator/bricks/bricks.go index da6cd739..df49c1ec 100644 --- a/internal/orchestrator/bricks/bricks.go +++ b/internal/orchestrator/bricks/bricks.go @@ -65,9 +65,6 @@ func (s *Service) List() (BrickListResult, error) { Category: brick.Category, Status: "installed", RequireModel: brick.RequireModel, - Models: f.Map(s.modelsIndex.GetModelsByBrick(brick.ID), func(m modelsindex.AIModel) string { - return m.ID - }), } } return res, nil diff --git a/internal/orchestrator/bricks/types.go b/internal/orchestrator/bricks/types.go index 3aa0afe3..1fca898f 100644 --- a/internal/orchestrator/bricks/types.go +++ b/internal/orchestrator/bricks/types.go @@ -20,14 +20,13 @@ type BrickListResult struct { } type BrickListItem struct { - ID string `json:"id"` - Name string `json:"name"` - Author string `json:"author"` - Description string `json:"description"` - Category string `json:"category"` - Status string `json:"status"` - RequireModel bool `json:"require_model"` - Models []string `json:"models"` + ID string `json:"id"` + Name string `json:"name"` + Author string `json:"author"` + Description string `json:"description"` + Category string `json:"category"` + Status string `json:"status"` + RequireModel bool `json:"require_model"` } type AppBrickInstancesResult struct { From 48ade4352602818d9d5b95e41cda71d3a8935040 Mon Sep 17 00:00:00 2001 From: Giulio Date: Wed, 26 Nov 2025 14:35:37 +0100 Subject: [PATCH 14/17] Update internal/orchestrator/bricksindex/testdata/bricks-list.yaml Co-authored-by: Davide --- internal/orchestrator/bricksindex/testdata/bricks-list.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/internal/orchestrator/bricksindex/testdata/bricks-list.yaml b/internal/orchestrator/bricksindex/testdata/bricks-list.yaml index 344bef7e..6794e27b 100644 --- a/internal/orchestrator/bricksindex/testdata/bricks-list.yaml +++ b/internal/orchestrator/bricksindex/testdata/bricks-list.yaml @@ -16,10 +16,6 @@ bricks: - name: EI_CLASSIFICATION_MODEL default_value: /models/ootb/ei/mobilenet-v2-224px.eim description: path to the model file -- id: arduino:model_required - name: Model Required Brick - description: A brick that requires a model - require_model: true - id: arduino:camera_scanner name: Camera Scanner description: Scans a camera for barcodes and QR codes From cefcbb9de10fcbfd9b9aeb158baa095f88015fc9 Mon Sep 17 00:00:00 2001 From: Giulio Date: Wed, 26 Nov 2025 14:35:46 +0100 Subject: [PATCH 15/17] Update internal/orchestrator/bricksindex/testdata/bricks-list.yaml Co-authored-by: Davide --- internal/orchestrator/bricksindex/testdata/bricks-list.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/orchestrator/bricksindex/testdata/bricks-list.yaml b/internal/orchestrator/bricksindex/testdata/bricks-list.yaml index 6794e27b..c494df17 100644 --- a/internal/orchestrator/bricksindex/testdata/bricks-list.yaml +++ b/internal/orchestrator/bricksindex/testdata/bricks-list.yaml @@ -136,3 +136,7 @@ bricks: description: Scans a camera for barcodes and QR codes require_container: false ports: [] +- id: arduino:model_required + name: Model Required Brick + description: A brick that requires a model + require_model: true From 5eb18f862932bcc034dc5dcb9c6646ba8a0348f1 Mon Sep 17 00:00:00 2001 From: Giulio Date: Wed, 26 Nov 2025 14:36:05 +0100 Subject: [PATCH 16/17] Update internal/orchestrator/bricks/testdata/bricks-list.yaml Co-authored-by: Davide --- .../bricks/testdata/bricks-list.yaml | 25 +++---------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/internal/orchestrator/bricks/testdata/bricks-list.yaml b/internal/orchestrator/bricks/testdata/bricks-list.yaml index 91660089..9a8c68c4 100644 --- a/internal/orchestrator/bricks/testdata/bricks-list.yaml +++ b/internal/orchestrator/bricks/testdata/bricks-list.yaml @@ -23,25 +23,8 @@ bricks: mount_devices_into_container: false ports: [] category: storage -- id: arduino:image_classification - name: Image Classification - description: "Brick for image classification using a pre-trained model. It processes\ - \ images and returns the predicted class label and confidence score.\nBrick is\ - \ designed to work with pre-trained models provided by framework or with custom\ - \ image classification models trained on Edge Impulse platform. \n" - require_container: true +- id: arduino:brick-with-require-model + name: A brick with required model + description: "Brick with required model" require_model: true - require_devices: false - mount_devices_into_container: false - ports: [] - category: video - model_name: mobilenet-image-classification - variables: - - name: CUSTOM_MODEL_PATH - default_value: /home/arduino/.arduino-bricks/ei-models - description: path to the custom model directory - - name: EI_CLASSIFICATION_MODEL - default_value: /models/ootb/ei/mobilenet-v2-224px.eim - description: path to the model file - - + model_name: mobilenet-image-classification \ No newline at end of file From ade42598d712d3b830556421dba1d5e89e67e38e Mon Sep 17 00:00:00 2001 From: Giulio Pilotto Date: Wed, 26 Nov 2025 14:45:22 +0100 Subject: [PATCH 17/17] revert --- internal/orchestrator/bricksindex/bricks_index.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/orchestrator/bricksindex/bricks_index.go b/internal/orchestrator/bricksindex/bricks_index.go index a8d39c8c..9e52f1c6 100644 --- a/internal/orchestrator/bricksindex/bricks_index.go +++ b/internal/orchestrator/bricksindex/bricks_index.go @@ -55,9 +55,9 @@ type Brick struct { Category string `yaml:"category,omitempty"` RequiresDisplay string `yaml:"requires_display,omitempty"` RequireContainer bool `yaml:"require_container"` + RequireModel bool `yaml:"require_model"` Variables []BrickVariable `yaml:"variables,omitempty"` Ports []string `yaml:"ports,omitempty"` - RequireModel bool `yaml:"require_model"` ModelName string `yaml:"model_name,omitempty"` MountDevicesIntoContainer bool `yaml:"mount_devices_into_container,omitempty"` RequiredDevices []string `yaml:"required_devices,omitempty"`