@@ -19,24 +19,28 @@ func TestLmstudioEnricher(t *testing.T) {
19 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
19 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
20 require.Equal(t, "/api/v1/models", r.URL.Path)
20 require.Equal(t, "/api/v1/models", r.URL.Path)
21 w.Header().Set("Content-Type", "application/json")
21 w.Header().Set("Content-Type", "application/json")
22− json.NewEncoder(w).Encode(lmstudioModelsResponse{
22+ // Raw JSON matching LM Studio's real /api/v1/models wire
23− Data: []lmstudioModelEntry{
23+ // format: array under "models", not "data".
24+ _, _ = w.Write([]byte(`{
25− Key: "qwen2.5-7b-instruct",
27+ "key": "qwen2.5-7b-instruct",
26− DisplayName: "Qwen 2.5 7B Instruct",
28+ "display_name": "Qwen 2.5 7B Instruct",
27− MaxContextLength: 32768,
29+ "max_context_length": 32768
30− Key: "llama-3.1-8b",
32+ "key": "llama-3.1-8b",
31− DisplayName: "Llama 3.1 8B",
33+ "display_name": "Llama 3.1 8B",
32− MaxContextLength: 131072,
34+ "max_context_length": 131072
37 defer srv.Close()
39 defer srv.Close()
41+ // Base URL includes /v1 (as Crush configures it); the enricher
42+ // strips it so the native endpoint resolves at the server root.
39− cfg := Config{ID: "test-lmstudio", BaseURL: srv.URL}
43+ cfg := Config{ID: "test-lmstudio", BaseURL: srv.URL + "/v1"}
40 models := []catwalk.Model{
44 models := []catwalk.Model{
41 {ID: "qwen2.5-7b-instruct", Name: "qwen2.5-7b-instruct"},
45 {ID: "qwen2.5-7b-instruct", Name: "qwen2.5-7b-instruct"},
42 {ID: "llama-3.1-8b", Name: "llama-3.1-8b"},
46 {ID: "llama-3.1-8b", Name: "llama-3.1-8b"},
@@ -60,7 +64,7 @@ func TestLmstudioEnricher(t *testing.T) {
60 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
64 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
61 w.Header().Set("Content-Type", "application/json")
65 w.Header().Set("Content-Type", "application/json")
62 json.NewEncoder(w).Encode(lmstudioModelsResponse{
66 json.NewEncoder(w).Encode(lmstudioModelsResponse{
63− Data: []lmstudioModelEntry{
67+ Models: []lmstudioModelEntry{
65 Key: "m1",
69 Key: "m1",
66 MaxContextLength: 131072,
70 MaxContextLength: 131072,
@@ -87,7 +91,7 @@ func TestLmstudioEnricher(t *testing.T) {
87 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
91 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
88 w.Header().Set("Content-Type", "application/json")
92 w.Header().Set("Content-Type", "application/json")
89 json.NewEncoder(w).Encode(lmstudioModelsResponse{
93 json.NewEncoder(w).Encode(lmstudioModelsResponse{
90− Data: []lmstudioModelEntry{
94+ Models: []lmstudioModelEntry{
92 Key: "m1",
96 Key: "m1",
93 DisplayName: "Should Not Override",
97 DisplayName: "Should Not Override",
@@ -132,7 +136,7 @@ func TestLmstudioEnricher(t *testing.T) {
132 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
136 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
133 w.Header().Set("Content-Type", "application/json")
137 w.Header().Set("Content-Type", "application/json")
134 json.NewEncoder(w).Encode(lmstudioModelsResponse{
138 json.NewEncoder(w).Encode(lmstudioModelsResponse{
135− Data: []lmstudioModelEntry{
139+ Models: []lmstudioModelEntry{
136 {Key: "m1", DisplayName: "API Name"},
140 {Key: "m1", DisplayName: "API Name"},