@@ -1761,16 +1761,37 @@ fn probeOpenAI(
17611761 transport : embedding_http.Transport ,
17621762 base_url : []const u8 ,
17631763) ? DetectedServer {
1764- const url = buildOpenAIModelsUrl (allocator , base_url ) catch return null ;
1765- defer allocator .free (url );
1764+ // Try /health first (oMLX returns 401 on /v1/models without auth)
1765+ const health_url = buildUrl (allocator , base_url , "/health" ) catch return null ;
1766+ defer allocator .free (health_url );
17661767
17671768 const headers = [_ ]std.http.Header {
17681769 .{ .name = "Accept" , .value = "application/json" },
17691770 };
17701771
1772+ if (transport .send (transport .ctx , allocator , .{
1773+ .method = "GET" ,
1774+ .url = health_url ,
1775+ .headers = & headers ,
1776+ .body = "" ,
1777+ })) | response | {
1778+ defer allocator .free (response .body );
1779+ if (response .status == 200 ) {
1780+ return .{
1781+ .url = base_url ,
1782+ .dialect = .openai ,
1783+ .model_available = true ,
1784+ };
1785+ }
1786+ } else | _ | {}
1787+
1788+ // Fall back to /v1/models
1789+ const models_url = buildUrl (allocator , base_url , "/v1/models" ) catch return null ;
1790+ defer allocator .free (models_url );
1791+
17711792 const response = transport .send (transport .ctx , allocator , .{
17721793 .method = "GET" ,
1773- .url = url ,
1794+ .url = models_url ,
17741795 .headers = & headers ,
17751796 .body = "" ,
17761797 }) catch return null ;
@@ -1785,9 +1806,9 @@ fn probeOpenAI(
17851806 };
17861807}
17871808
1788- fn buildOpenAIModelsUrl (allocator : std.mem.Allocator , base_url : []const u8 ) ! []u8 {
1809+ fn buildUrl (allocator : std.mem.Allocator , base_url : [] const u8 , path : []const u8 ) ! []u8 {
17891810 const trimmed = std .mem .trimRight (u8 , base_url , "/" );
1790- return std .fmt .allocPrint (allocator , "{s}/v1/models " , .{trimmed });
1811+ return std .fmt .allocPrint (allocator , "{s}{s} " , .{ trimmed , path });
17911812}
17921813
17931814/// Prompts the user with a yes/no question. Returns true for yes.
@@ -5719,6 +5740,9 @@ pub fn runRegexSearch(
57195740
57205741const OpenAIFallbackMock = struct {
57215742 fn send (_ : * anyopaque , allocator : std.mem.Allocator , req : embedding_http.HttpRequest ) ! embedding_http.HttpResponse {
5743+ if (std .mem .endsWith (u8 , req .url , "/health" )) {
5744+ return .{ .status = 200 , .body = try allocator .dupe (u8 , "{\" status\" :\" healthy\" }" ) };
5745+ }
57225746 if (std .mem .endsWith (u8 , req .url , "/v1/models" )) {
57235747 return .{ .status = 200 , .body = try allocator .dupe (u8 , "{\" data\" :[]}" ) };
57245748 }
0 commit comments