@@ -21,6 +21,7 @@ import (
2121
2222func newListCmd () * cobra.Command {
2323 var jsonFormat , openai , quiet bool
24+ var openaiURL string
2425 c := & cobra.Command {
2526 Use : "list [OPTIONS] [MODEL]" ,
2627 Aliases : []string {"ls" },
@@ -31,6 +32,46 @@ func newListCmd() *cobra.Command {
3132 return fmt .Errorf ("--quiet flag cannot be used with --openai flag or OpenAI backend" )
3233 }
3334
35+ // Handle --openaiurl flag for external OpenAI endpoints
36+ if openaiURL != "" {
37+ if quiet {
38+ return fmt .Errorf ("--quiet flag cannot be used with --openaiurl flag" )
39+ }
40+ ctx , err := desktop .NewContextForOpenAI (openaiURL )
41+ if err != nil {
42+ return fmt .Errorf ("invalid OpenAI URL: %w" , err )
43+ }
44+ client := desktop .New (ctx )
45+ models , err := client .ListOpenAI ()
46+ if err != nil {
47+ return handleClientError (err , "Failed to list models from OpenAI endpoint" )
48+ }
49+ var modelFilter string
50+ if len (args ) > 0 {
51+ modelFilter = args [0 ]
52+ }
53+ if modelFilter != "" {
54+ filtered := models .Data [:0 ]
55+ for _ , m := range models .Data {
56+ if matchesModelFilter (m .ID , modelFilter ) {
57+ filtered = append (filtered , m )
58+ }
59+ }
60+ models .Data = filtered
61+ }
62+ if jsonFormat {
63+ output , err := formatter .ToStandardJSON (models )
64+ if err != nil {
65+ return err
66+ }
67+ fmt .Fprint (cmd .OutOrStdout (), output )
68+ return nil
69+ }
70+ // Display in table format with only MODEL NAME populated
71+ fmt .Fprint (cmd .OutOrStdout (), prettyPrintOpenAIModels (models ))
72+ return nil
73+ }
74+
3475 // If we're doing an automatic install, only show the installation
3576 // status if it won't corrupt machine-readable output.
3677 var standaloneInstallPrinter standalone.StatusPrinter
@@ -56,6 +97,7 @@ func newListCmd() *cobra.Command {
5697 c .Flags ().BoolVar (& jsonFormat , "json" , false , "List models in a JSON format" )
5798 c .Flags ().BoolVar (& openai , "openai" , false , "List models in an OpenAI format" )
5899 c .Flags ().BoolVarP (& quiet , "quiet" , "q" , false , "Only show model IDs" )
100+ c .Flags ().StringVar (& openaiURL , "openaiurl" , "" , "OpenAI-compatible API endpoint URL to list models from" )
59101 return c
60102}
61103
@@ -239,3 +281,24 @@ func appendRow(table *tablewriter.Table, tag string, model dmrm.Model) {
239281 model .Config .Size ,
240282 })
241283}
284+
285+ // prettyPrintOpenAIModels formats OpenAI model list in table format with only MODEL NAME populated
286+ func prettyPrintOpenAIModels (models dmrm.OpenAIModelList ) string {
287+ // Sort models by ID
288+ sort .Slice (models .Data , func (i , j int ) bool {
289+ return strings .ToLower (models .Data [i ].ID ) < strings .ToLower (models .Data [j ].ID )
290+ })
291+
292+ var buf bytes.Buffer
293+ table := newTable (& buf )
294+ table .Header ([]string {"MODEL NAME" , "CREATED" })
295+ for _ , model := range models .Data {
296+ table .Append ([]string {
297+ model .ID ,
298+ units .HumanDuration (time .Since (time .Unix (model .Created , 0 ))) + " ago" ,
299+ })
300+ }
301+
302+ table .Render ()
303+ return buf .String ()
304+ }
0 commit comments