Skip to content

Commit a520a42

Browse files
committed
add model list info lite on brick list
1 parent 537694f commit a520a42

File tree

7 files changed

+104
-19
lines changed

7 files changed

+104
-19
lines changed

internal/api/docs/openapi.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1171,6 +1171,8 @@ components:
11711171
runner:
11721172
type: string
11731173
type: object
1174+
AIModelLite:
1175+
type: object
11741176
AIModelsListResult:
11751177
properties:
11761178
models:
@@ -1367,7 +1369,7 @@ components:
13671369
type: string
13681370
models:
13691371
items:
1370-
type: string
1372+
$ref: '#/components/schemas/AIModelLite'
13711373
nullable: true
13721374
type: array
13731375
name:

internal/e2e/client/client.gen.go

Lines changed: 11 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/e2e/daemon/brick_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"context"
2020
"encoding/json"
2121
"fmt"
22+
"io"
2223
"net/http"
2324
"testing"
2425

@@ -28,8 +29,10 @@ import (
2829

2930
"github.com/arduino/arduino-app-cli/internal/api/models"
3031
"github.com/arduino/arduino-app-cli/internal/e2e/client"
32+
"github.com/arduino/arduino-app-cli/internal/orchestrator/bricks"
3133
"github.com/arduino/arduino-app-cli/internal/orchestrator/bricksindex"
3234
"github.com/arduino/arduino-app-cli/internal/orchestrator/config"
35+
"github.com/arduino/arduino-app-cli/internal/orchestrator/modelsindex"
3336
"github.com/arduino/arduino-app-cli/internal/store"
3437
)
3538

@@ -83,6 +86,47 @@ func TestBricksList(t *testing.T) {
8386
require.Equal(t, bIdx.Description, *brick.Description)
8487
require.Equal(t, "Arduino", *brick.Author)
8588
require.Equal(t, "installed", *brick.Status)
89+
require.Nil(t, brick.Models)
90+
}
91+
}
92+
93+
func TestBricksListModelListInfoLite(t *testing.T) {
94+
httpClient := GetHttpclient(t)
95+
96+
response, err := httpClient.GetBricks(t.Context(), func(ctx context.Context, req *http.Request) error { return nil })
97+
require.NoError(t, err)
98+
defer response.Body.Close()
99+
100+
require.Equal(t, http.StatusOK, response.StatusCode, "Expected HTTP 200 OK")
101+
102+
body, err := io.ReadAll(response.Body)
103+
require.NoError(t, err, "Failed to read response body")
104+
105+
var result bricks.BrickListResult
106+
err = json.Unmarshal(body, &result)
107+
require.NoError(t, err, "Failed to unmarshal JSON response into BrickListResult")
108+
require.NotEmpty(t, result.Bricks, "Bricks list should not be empty")
109+
110+
expectedModelLiteInfo := []modelsindex.AIModelLite{
111+
{
112+
ID: "face-detection",
113+
Name: "Lightweight-Face-Detection",
114+
ModuleDescription: "Face bounding box detection. This model is trained on the WIDER FACE dataset and can detect faces in images.",
115+
},
116+
{
117+
ID: "yolox-object-detection",
118+
Name: "General purpose object detection - YoloX",
119+
ModuleDescription: "General purpose object detection model based on YoloX Nano. This model is trained on the COCO dataset and can detect 80 different object classes.",
120+
}}
121+
122+
for _, brick := range result.Bricks {
123+
switch brick.ID {
124+
case "arduino:object_detection":
125+
require.NotNil(t, brick.Models)
126+
require.Equal(t, expectedModelLiteInfo, brick.Models)
127+
case "arduino:dbstorage_sqlstore":
128+
require.Empty(t, brick.Models)
129+
}
86130
}
87131
}
88132

internal/orchestrator/bricks/bricks.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,7 @@ func (s *Service) List() (BrickListResult, error) {
6464
Description: brick.Description,
6565
Category: brick.Category,
6666
Status: "installed",
67-
Models: f.Map(s.modelsIndex.GetModelsByBrick(brick.ID), func(m modelsindex.AIModel) string {
68-
return m.ID
69-
}),
67+
Models: s.modelsIndex.GetModelsLiteInfoByBrick(brick.ID),
7068
}
7169
}
7270
return res, nil

internal/orchestrator/bricks/types.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,20 @@
1515

1616
package bricks
1717

18+
import "github.com/arduino/arduino-app-cli/internal/orchestrator/modelsindex"
19+
1820
type BrickListResult struct {
1921
Bricks []BrickListItem `json:"bricks"`
2022
}
2123

2224
type BrickListItem struct {
23-
ID string `json:"id"`
24-
Name string `json:"name"`
25-
Author string `json:"author"`
26-
Description string `json:"description"`
27-
Category string `json:"category"`
28-
Status string `json:"status"`
29-
Models []string `json:"models"`
25+
ID string `json:"id"`
26+
Name string `json:"name"`
27+
Author string `json:"author"`
28+
Description string `json:"description"`
29+
Category string `json:"category"`
30+
Status string `json:"status"`
31+
Models []modelsindex.AIModelLite `json:"models"`
3032
}
3133

3234
type AppBrickInstancesResult struct {

internal/orchestrator/modelsindex/models_index.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ type AIModel struct {
5353
ModelConfiguration map[string]string `yaml:"model_configuration,omitempty"`
5454
}
5555

56+
type AIModelLite struct {
57+
ID string `yaml:"-"`
58+
Name string `yaml:"name"`
59+
ModuleDescription string `yaml:"description"`
60+
}
61+
5662
type ModelsIndex struct {
5763
models []AIModel
5864
}
@@ -82,6 +88,25 @@ func (m *ModelsIndex) GetModelsByBrick(brick string) []AIModel {
8288
return matches
8389
}
8490

91+
func (m *ModelsIndex) GetModelsLiteInfoByBrick(brick string) []AIModelLite {
92+
var matches []AIModelLite
93+
for i := range m.models {
94+
if len(m.models[i].Bricks) > 0 && slices.Contains(m.models[i].Bricks, brick) {
95+
matches = append(matches,
96+
AIModelLite{
97+
ID: m.models[i].ID,
98+
Name: m.models[i].Name,
99+
ModuleDescription: m.models[i].ModuleDescription,
100+
},
101+
)
102+
}
103+
}
104+
if len(matches) == 0 {
105+
return nil
106+
}
107+
return matches
108+
}
109+
85110
func (m *ModelsIndex) GetModelsByBricks(bricks []string) []AIModel {
86111
var matchingModels []AIModel
87112
for _, model := range m.models {

internal/orchestrator/modelsindex/modelsindex_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,15 @@ func TestModelsIndex(t *testing.T) {
6969
assert.Equal(t, "face-detection", models[0].ID)
7070
assert.Equal(t, "yolox-object-detection", models[1].ID)
7171
})
72+
73+
t.Run("it gets models lite by a brick", func(t *testing.T) {
74+
model := modelsIndex.GetModelsLiteInfoByBrick("not-existing-brick")
75+
assert.Nil(t, model)
76+
77+
model = modelsIndex.GetModelsLiteInfoByBrick("arduino:object_detection")
78+
assert.Len(t, model, 1)
79+
assert.Equal(t, "face-detection", model[0].ID)
80+
assert.Equal(t, "Face bounding box detection. This model is trained on the WIDER FACE dataset and can detect faces in images.", model[0].ModuleDescription)
81+
assert.Equal(t, "Lightweight-Face-Detection", model[0].Name)
82+
})
7283
}

0 commit comments

Comments
 (0)