Skip to content

Commit 19c9d62

Browse files
authored
Fix: get /apps/:id/bricks must return the same response as /apps/:id/bricks/:id (#167)
* Unify BrickInstance types and add getSelectedModelOrDefault helper
1 parent 46e4f4c commit 19c9d62

File tree

4 files changed

+59
-52
lines changed

4 files changed

+59
-52
lines changed

internal/api/docs/openapi.yaml

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,7 +1194,7 @@ components:
11941194
properties:
11951195
bricks:
11961196
items:
1197-
$ref: '#/components/schemas/BrickInstanceListItem'
1197+
$ref: '#/components/schemas/BrickInstance'
11981198
nullable: true
11991199
type: array
12001200
type: object
@@ -1355,7 +1355,6 @@ components:
13551355
$ref: '#/components/schemas/BrickVariable'
13561356
description: 'Deprecated: use config_variables instead. This field is kept
13571357
for backward compatibility.'
1358-
nullable: true
13591358
type: object
13601359
type: object
13611360
BrickInstance:
@@ -1390,33 +1389,6 @@ components:
13901389
for backward compatibility.'
13911390
type: object
13921391
type: object
1393-
BrickInstanceListItem:
1394-
properties:
1395-
author:
1396-
type: string
1397-
category:
1398-
type: string
1399-
config_variables:
1400-
items:
1401-
$ref: '#/components/schemas/BrickConfigVariable'
1402-
type: array
1403-
id:
1404-
type: string
1405-
model:
1406-
type: string
1407-
name:
1408-
type: string
1409-
require_model:
1410-
type: boolean
1411-
status:
1412-
type: string
1413-
variables:
1414-
additionalProperties:
1415-
type: string
1416-
description: 'Deprecated: use config_variables instead. This field is kept
1417-
for backward compatibility.'
1418-
type: object
1419-
type: object
14201392
BrickListItem:
14211393
properties:
14221394
author:

internal/orchestrator/bricks/bricks.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package bricks
1717

1818
import (
19+
"cmp"
1920
"errors"
2021
"fmt"
2122
"log/slog"
@@ -71,7 +72,7 @@ func (s *Service) List() (BrickListResult, error) {
7172
}
7273

7374
func (s *Service) AppBrickInstancesList(a *app.ArduinoApp) (AppBrickInstancesResult, error) {
74-
res := AppBrickInstancesResult{BrickInstances: make([]BrickInstanceListItem, len(a.Descriptor.Bricks))}
75+
res := AppBrickInstancesResult{BrickInstances: make([]BrickInstance, len(a.Descriptor.Bricks))}
7576
for i, brickInstance := range a.Descriptor.Bricks {
7677
brick, found := s.bricksIndex.FindBrickByID(brickInstance.ID)
7778
if !found {
@@ -80,16 +81,23 @@ func (s *Service) AppBrickInstancesList(a *app.ArduinoApp) (AppBrickInstancesRes
8081

8182
variablesMap, configVariables := getInstanceBrickConfigVariableDetails(brick, brickInstance.Variables)
8283

83-
res.BrickInstances[i] = BrickInstanceListItem{
84+
res.BrickInstances[i] = BrickInstance{
8485
ID: brick.ID,
8586
Name: brick.Name,
8687
Author: "Arduino", // TODO: for now we only support our bricks
8788
Category: brick.Category,
8889
Status: "installed",
8990
RequireModel: brick.RequireModel,
90-
ModelID: brickInstance.Model, // TODO: in case is not set by the user, should we return the default model?
91-
Variables: variablesMap, // TODO: do we want to show also the default value of not explicitly set variables?
91+
ModelID: cmp.Or(brickInstance.Model, brick.ModelName),
92+
Variables: variablesMap,
9293
ConfigVariables: configVariables,
94+
CompatibleModels: f.Map(s.modelsIndex.GetModelsByBrick(brick.ID), func(m modelsindex.AIModel) AIModel {
95+
return AIModel{
96+
ID: m.ID,
97+
Name: m.Name,
98+
Description: m.ModuleDescription,
99+
}
100+
}),
93101
}
94102

95103
}
@@ -109,11 +117,6 @@ func (s *Service) AppBrickInstanceDetails(a *app.ArduinoApp, brickID string) (Br
109117

110118
variables, configVariables := getInstanceBrickConfigVariableDetails(brick, a.Descriptor.Bricks[brickIndex].Variables)
111119

112-
modelID := a.Descriptor.Bricks[brickIndex].Model
113-
if modelID == "" {
114-
modelID = brick.ModelName
115-
}
116-
117120
return BrickInstance{
118121
ID: brickID,
119122
Name: brick.Name,
@@ -123,7 +126,7 @@ func (s *Service) AppBrickInstanceDetails(a *app.ArduinoApp, brickID string) (Br
123126
RequireModel: brick.RequireModel,
124127
Variables: variables,
125128
ConfigVariables: configVariables,
126-
ModelID: modelID,
129+
ModelID: cmp.Or(a.Descriptor.Bricks[brickIndex].Model, brick.ModelName),
127130
CompatibleModels: f.Map(s.modelsIndex.GetModelsByBrick(brick.ID), func(m modelsindex.AIModel) AIModel {
128131
return AIModel{
129132
ID: m.ID,

internal/orchestrator/bricks/bricks_test.go

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,21 @@ func TestAppBrickInstancesList(t *testing.T) {
733733

734734
svc := &Service{
735735
bricksIndex: bIndex,
736-
modelsIndex: &modelsindex.ModelsIndex{},
736+
modelsIndex: &modelsindex.ModelsIndex{
737+
Models: []modelsindex.AIModel{
738+
{
739+
ID: "yolox-object-detection",
740+
Name: "General purpose object detection - YoloX",
741+
ModuleDescription: "a-model-description",
742+
Bricks: []string{"arduino:object_detection"},
743+
},
744+
{
745+
ID: "face-detection",
746+
Name: "Lightweight-Face-Detection",
747+
Bricks: []string{"arduino:object_detection"},
748+
},
749+
},
750+
},
737751
}
738752

739753
tests := []struct {
@@ -809,6 +823,10 @@ func TestAppBrickInstancesList(t *testing.T) {
809823
require.Equal(t, "video", brick.Category)
810824
require.True(t, brick.RequireModel)
811825
require.Equal(t, "face-detection", brick.ModelID)
826+
require.Equal(t, []AIModel{
827+
{ID: "yolox-object-detection", Name: "General purpose object detection - YoloX", Description: "a-model-description"},
828+
{ID: "face-detection", Name: "Lightweight-Face-Detection", Description: ""},
829+
}, brick.CompatibleModels)
812830

813831
foundCustom := false
814832
for _, v := range brick.ConfigVariables {
@@ -820,6 +838,30 @@ func TestAppBrickInstancesList(t *testing.T) {
820838
require.True(t, foundCustom, "Variable CUSTOM_MODEL_PATH should be present and overridden")
821839
},
822840
},
841+
{
842+
name: "Success - Brick using brick default model",
843+
app: &app.ArduinoApp{
844+
Descriptor: app.AppDescriptor{
845+
Bricks: []app.Brick{
846+
{
847+
ID: "arduino:object_detection",
848+
},
849+
},
850+
},
851+
},
852+
validate: func(t *testing.T, res AppBrickInstancesResult) {
853+
require.Len(t, res.BrickInstances, 1)
854+
brick := res.BrickInstances[0]
855+
856+
require.Equal(t, "arduino:object_detection", brick.ID)
857+
require.True(t, brick.RequireModel)
858+
require.Equal(t, "yolox-object-detection", brick.ModelID)
859+
require.Equal(t, []AIModel{
860+
{ID: "yolox-object-detection", Name: "General purpose object detection - YoloX", Description: "a-model-description"},
861+
{ID: "face-detection", Name: "Lightweight-Face-Detection", Description: ""},
862+
}, brick.CompatibleModels)
863+
},
864+
},
823865
{
824866
name: "Success - Multiple Bricks",
825867
app: &app.ArduinoApp{

internal/orchestrator/bricks/types.go

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,9 @@ type BrickListItem struct {
3030
}
3131

3232
type AppBrickInstancesResult struct {
33-
BrickInstances []BrickInstanceListItem `json:"bricks"`
34-
}
35-
type BrickInstanceListItem struct {
36-
ID string `json:"id"`
37-
Name string `json:"name"`
38-
Author string `json:"author"`
39-
Category string `json:"category"`
40-
Status string `json:"status"`
41-
Variables map[string]string `json:"variables,omitempty" description:"Deprecated: use config_variables instead. This field is kept for backward compatibility."`
42-
ConfigVariables []BrickConfigVariable `json:"config_variables,omitempty"`
43-
RequireModel bool `json:"require_model"`
44-
ModelID string `json:"model,omitempty"`
33+
BrickInstances []BrickInstance `json:"bricks"`
4534
}
35+
4636
type BrickInstance struct {
4737
ID string `json:"id"`
4838
Name string `json:"name"`

0 commit comments

Comments
 (0)