客户端需要 Manager 下发用户可用模型作唯一来源(里程碑04 收尾)。
- GET /api/heicode/available-models(挂 UserOrV2DeviceAuth,与 /api/heicode/self 同
设备配对鉴权)。
- 服务端解析:user.Group → service.GetUserUsableGroups → model.GetGroupEnabledModels
(与 GetUserModels 同源),去重排序。
- 客户端安全形状 {model_id, display_name, default}:绝不下发 channelId/base_url/
api_key/provider_type/单价(buildAvailableModelItems 纯函数 + 测试断言不泄露)。
- default 标记取 defaultAgentModelID()。
可选字段 capabilities/context_window/cost_tier 暂不下发(HM 无可靠来源,避免臆造;
客户端按可选处理)。etag/updated_at 可作后续。
Fixes #25
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
39 lines
1.3 KiB
Go
39 lines
1.3 KiB
Go
package controller
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// buildAvailableModelItems must emit only the client-safe fields (model_id /
|
|
// display_name / default), flag exactly the default model, and never leak
|
|
// server-side routing fields. (#25)
|
|
func TestBuildAvailableModelItems(t *testing.T) {
|
|
items := buildAvailableModelItems([]string{"heicode-pro", "heicode-lite"}, "heicode-pro")
|
|
require.Len(t, items, 2)
|
|
|
|
require.Equal(t, "heicode-pro", items[0]["model_id"])
|
|
require.Equal(t, "heicode-pro", items[0]["display_name"])
|
|
require.Equal(t, true, items[0]["default"])
|
|
|
|
require.Equal(t, "heicode-lite", items[1]["model_id"])
|
|
require.Equal(t, false, items[1]["default"])
|
|
|
|
// client-safe: no server-only fields leak
|
|
for _, it := range items {
|
|
for _, banned := range []string{"channelId", "channel_id", "base_url", "api_key", "api_key_ref", "provider_type", "price", "ratio"} {
|
|
_, present := it[banned]
|
|
require.False(t, present, "field %q must not be exposed to client", banned)
|
|
}
|
|
require.Len(t, it, 3) // exactly model_id, display_name, default
|
|
}
|
|
|
|
// no default in the list -> none flagged
|
|
none := buildAvailableModelItems([]string{"a", "b"}, "zzz")
|
|
require.Equal(t, false, none[0]["default"])
|
|
require.Equal(t, false, none[1]["default"])
|
|
|
|
require.Empty(t, buildAvailableModelItems(nil, "x"))
|
|
}
|