@@ -21,6 +21,8 @@ import (
2121 "go.opentelemetry.io/otel"
2222)
2323
24+ const DefaultBackend = "llama.cpp"
25+
2426var (
2527 ErrNotFound = errors .New ("model not found" )
2628 ErrServiceUnavailable = errors .New ("service unavailable" )
@@ -236,14 +238,30 @@ func (c *Client) List() ([]dmrm.Model, error) {
236238 return modelsJson , nil
237239}
238240
239- func (c * Client ) ListOpenAI () (dmrm.OpenAIModelList , error ) {
240- modelsRoute := inference .InferencePrefix + "/v1/models"
241- rawResponse , err := c .listRaw (modelsRoute , "" )
241+ func (c * Client ) ListOpenAI (backend , apiKey string ) (dmrm.OpenAIModelList , error ) {
242+ if backend == "" {
243+ backend = DefaultBackend
244+ }
245+ modelsRoute := fmt .Sprintf ("%s/%s/v1/models" , inference .InferencePrefix , backend )
246+
247+ // Use doRequestWithAuth to support API key authentication
248+ resp , err := c .doRequestWithAuth (http .MethodGet , modelsRoute , nil , "openai" , apiKey )
249+ if err != nil {
250+ return dmrm.OpenAIModelList {}, c .handleQueryError (err , modelsRoute )
251+ }
252+ defer resp .Body .Close ()
253+
254+ if resp .StatusCode != http .StatusOK {
255+ return dmrm.OpenAIModelList {}, fmt .Errorf ("failed to list models: %s" , resp .Status )
256+ }
257+
258+ body , err := io .ReadAll (resp .Body )
242259 if err != nil {
243- return dmrm.OpenAIModelList {}, err
260+ return dmrm.OpenAIModelList {}, fmt . Errorf ( "failed to read response body: %w" , err )
244261 }
262+
245263 var modelsJson dmrm.OpenAIModelList
246- if err := json .Unmarshal (rawResponse , & modelsJson ); err != nil {
264+ if err := json .Unmarshal (body , & modelsJson ); err != nil {
247265 return modelsJson , fmt .Errorf ("failed to unmarshal response body: %w" , err )
248266 }
249267 return modelsJson , nil
@@ -343,7 +361,7 @@ func (c *Client) fullModelID(id string) (string, error) {
343361 return "" , fmt .Errorf ("model with ID %s not found" , id )
344362}
345363
346- func (c * Client ) Chat (model , prompt string ) error {
364+ func (c * Client ) Chat (backend , model , prompt , apiKey string ) error {
347365 model = normalizeHuggingFaceModelName (model )
348366 if ! strings .Contains (strings .Trim (model , "/" ), "/" ) {
349367 // Do an extra API call to check if the model parameter isn't a model ID.
@@ -368,14 +386,22 @@ func (c *Client) Chat(model, prompt string) error {
368386 return fmt .Errorf ("error marshaling request: %w" , err )
369387 }
370388
371- chatCompletionsPath := inference .InferencePrefix + "/v1/chat/completions"
372- resp , err := c .doRequest (
389+ var completionsPath string
390+ if backend != "" {
391+ completionsPath = inference .InferencePrefix + "/" + backend + "/v1/chat/completions"
392+ } else {
393+ completionsPath = inference .InferencePrefix + "/v1/chat/completions"
394+ }
395+
396+ resp , err := c .doRequestWithAuth (
373397 http .MethodPost ,
374- chatCompletionsPath ,
398+ completionsPath ,
375399 bytes .NewReader (jsonData ),
400+ backend ,
401+ apiKey ,
376402 )
377403 if err != nil {
378- return c .handleQueryError (err , chatCompletionsPath )
404+ return c .handleQueryError (err , completionsPath )
379405 }
380406 defer resp .Body .Close ()
381407
@@ -604,6 +630,11 @@ func (c *Client) ConfigureBackend(request scheduling.ConfigureRequest) error {
604630
605631// doRequest is a helper function that performs HTTP requests and handles 503 responses
606632func (c * Client ) doRequest (method , path string , body io.Reader ) (* http.Response , error ) {
633+ return c .doRequestWithAuth (method , path , body , "" , "" )
634+ }
635+
636+ // doRequestWithAuth is a helper function that performs HTTP requests with optional authentication
637+ func (c * Client ) doRequestWithAuth (method , path string , body io.Reader , backend , apiKey string ) (* http.Response , error ) {
607638 req , err := http .NewRequest (method , c .modelRunner .URL (path ), body )
608639 if err != nil {
609640 return nil , fmt .Errorf ("error creating request: %w" , err )
@@ -613,6 +644,12 @@ func (c *Client) doRequest(method, path string, body io.Reader) (*http.Response,
613644 }
614645
615646 req .Header .Set ("User-Agent" , "docker-model-cli/" + Version )
647+
648+ // Add Authorization header for OpenAI backend
649+ if apiKey != "" {
650+ req .Header .Set ("Authorization" , "Bearer " + apiKey )
651+ }
652+
616653 resp , err := c .modelRunner .Client ().Do (req )
617654 if err != nil {
618655 return nil , err
0 commit comments