Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
04404f4
Start on 'view' command
cheshire137 Oct 8, 2024
2ac9122
Prompt to select a model if none specified
cheshire137 Oct 8, 2024
08b184a
Add util.GetValidModelName
cheshire137 Oct 8, 2024
5ebf021
Bail early when specified model name is invalid
cheshire137 Oct 8, 2024
1e92fd9
Bail early when provided model name for 'run' is invalid
cheshire137 Oct 8, 2024
f9b7694
Replace with ValidateModelName
cheshire137 Oct 8, 2024
c873994
Replace with GetModelByName, output friendly name
cheshire137 Oct 8, 2024
07858b8
Pull out LightGrayUnderline shared color
cheshire137 Oct 8, 2024
8602571
Pull out modelPrinter type
cheshire137 Oct 8, 2024
b995626
Show publisher and summary fields
cheshire137 Oct 8, 2024
7aa576e
Pull out azureAiStudioURL constant
cheshire137 Oct 8, 2024
d75afc9
Start on client GetModelDetails
cheshire137 Oct 8, 2024
02ca397
Get the version and registry name, too
cheshire137 Oct 8, 2024
a042eb6
Dump out model details at the end
cheshire137 Oct 8, 2024
4f833dc
Add modelCatalogDetailsResponse type
cheshire137 Oct 8, 2024
0a56b20
Display model description from details
cheshire137 Oct 8, 2024
bb9e140
Output license details with 'view' command
cheshire137 Oct 8, 2024
509238f
Merge branch 'main' into view-cmd
cheshire137 Oct 9, 2024
584ac6e
Drop centralized colors
cheshire137 Oct 9, 2024
fdd8d03
Move getModelByName into view package
cheshire137 Oct 9, 2024
c924fe4
Add HasName to ModelSummary
cheshire137 Oct 9, 2024
287062a
Display model notes, add blank line between multi-line fields
cheshire137 Oct 9, 2024
2606848
Include tags in view output
cheshire137 Oct 9, 2024
4ecefd9
Don't output labels for blank values
cheshire137 Oct 9, 2024
c1da574
Display supported inputs and outputs
cheshire137 Oct 9, 2024
73fd787
Display 'evaluation' field
cheshire137 Oct 9, 2024
3600097
Use snake case for JSON fields like our other external-facing types
cheshire137 Oct 9, 2024
b761cee
Display supported languages
cheshire137 Oct 9, 2024
adfefec
Display context max tokens
cheshire137 Oct 9, 2024
d2ccb20
Display rate limit tier
cheshire137 Oct 9, 2024
0e61970
Do some Markdown processing on multi-line fields
cheshire137 Oct 9, 2024
c62a6cc
Don't truncate list of languages
cheshire137 Oct 9, 2024
4c441d9
Reduce whitespace in output
cheshire137 Oct 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmd
import (
"github.com/github/gh-models/cmd/list"
"github.com/github/gh-models/cmd/run"
"github.com/github/gh-models/cmd/view"
"github.com/spf13/cobra"
)

Expand All @@ -14,6 +15,7 @@ func NewRootCommand() *cobra.Command {

cmd.AddCommand(list.NewListCommand())
cmd.AddCommand(run.NewRunCommand())
cmd.AddCommand(view.NewViewCommand())

return cmd
}
2 changes: 1 addition & 1 deletion cmd/run/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ func NewRunCommand() *cobra.Command {

foundMatch := false
for _, model := range models {
if strings.EqualFold(model.FriendlyName, modelName) || strings.EqualFold(model.Name, modelName) {
if model.HasName(modelName) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice

modelName = model.Name
foundMatch = true
break
Expand Down
95 changes: 95 additions & 0 deletions cmd/view/model_printer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package view

import (
"strings"

"github.com/cli/cli/v2/pkg/markdown"
"github.com/cli/go-gh/v2/pkg/tableprinter"
"github.com/cli/go-gh/v2/pkg/term"
"github.com/github/gh-models/internal/azure_models"
"github.com/mgutz/ansi"
)

var (
lightGrayUnderline = ansi.ColorFunc("white+du")
)

type modelPrinter struct {
modelSummary *azure_models.ModelSummary
modelDetails *azure_models.ModelDetails
printer tableprinter.TablePrinter
terminalWidth int
}

func newModelPrinter(summary *azure_models.ModelSummary, details *azure_models.ModelDetails, terminal term.Term) modelPrinter {
width, _, _ := terminal.Size()
printer := tableprinter.New(terminal.Out(), terminal.IsTerminalOutput(), width)
return modelPrinter{modelSummary: summary, modelDetails: details, printer: printer, terminalWidth: width}
}

func (p *modelPrinter) render() error {
modelSummary := p.modelSummary
if modelSummary != nil {
p.printLabelledLine("Display name:", modelSummary.FriendlyName)
p.printLabelledLine("Summary name:", modelSummary.Name)
p.printLabelledLine("Publisher:", modelSummary.Publisher)
p.printLabelledLine("Summary:", modelSummary.Summary)
}

modelDetails := p.modelDetails
if modelDetails != nil {
p.printLabelledLine("Context:", modelDetails.ContextLimits())
p.printLabelledLine("Rate limit tier:", modelDetails.RateLimitTier)
p.printLabelledList("Tags:", modelDetails.Tags)
p.printLabelledList("Supported input types:", modelDetails.SupportedInputModalities)
p.printLabelledList("Supported output types:", modelDetails.SupportedOutputModalities)
p.printLabelledMultiLineList("Supported languages:", modelDetails.SupportedLanguages)
p.printLabelledLine("License:", modelDetails.License)
p.printMultipleLinesWithLabel("License description:", modelDetails.LicenseDescription)
p.printMultipleLinesWithLabel("Description:", modelDetails.Description)
p.printMultipleLinesWithLabel("Notes:", modelDetails.Notes)
p.printMultipleLinesWithLabel("Evaluation:", modelDetails.Evaluation)
}

err := p.printer.Render()
if err != nil {
return err
}

return nil
}

func (p *modelPrinter) printLabelledLine(label string, value string) {
if value == "" {
return
}
p.addLabel(label)
p.printer.AddField(strings.TrimSpace(value))
p.printer.EndRow()
}

func (p *modelPrinter) printLabelledList(label string, values []string) {
p.printLabelledLine(label, strings.Join(values, ", "))
}

func (p *modelPrinter) printLabelledMultiLineList(label string, values []string) {
p.printMultipleLinesWithLabel(label, strings.Join(values, ", "))
}

func (p *modelPrinter) printMultipleLinesWithLabel(label string, value string) {
if value == "" {
return
}
p.addLabel(label)
renderedValue, err := markdown.Render(strings.TrimSpace(value), markdown.WithWrap(p.terminalWidth))
displayValue := value
if err == nil {
displayValue = renderedValue
}
p.printer.AddField(displayValue, tableprinter.WithTruncate(nil))
p.printer.EndRow()
}

func (p *modelPrinter) addLabel(label string) {
p.printer.AddField(label, tableprinter.WithTruncate(nil), tableprinter.WithColor(lightGrayUnderline))
}
94 changes: 94 additions & 0 deletions cmd/view/view.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package view

import (
"fmt"
"io"

"github.com/AlecAivazis/survey/v2"
"github.com/cli/go-gh/v2/pkg/auth"
"github.com/cli/go-gh/v2/pkg/term"
"github.com/github/gh-models/internal/azure_models"
"github.com/github/gh-models/internal/ux"
"github.com/spf13/cobra"
)

func NewViewCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "view [model]",
Short: "View details about a model",
Args: cobra.ArbitraryArgs,
RunE: func(cmd *cobra.Command, args []string) error {
terminal := term.FromEnv()

token, _ := auth.TokenForHost("github.com")
if token == "" {
io.WriteString(terminal.Out(), "No GitHub token found. Please run 'gh auth login' to authenticate.\n")
return nil
}

client := azure_models.NewClient(token)

models, err := client.ListModels()
if err != nil {
return err
}

ux.SortModels(models)

modelName := ""
switch {
case len(args) == 0:
// Need to prompt for a model
prompt := &survey.Select{
Message: "Select a model:",
Options: []string{},
}

for _, model := range models {
if !ux.IsChatModel(model) {
continue
}
prompt.Options = append(prompt.Options, model.FriendlyName)
}

err = survey.AskOne(prompt, &modelName, survey.WithPageSize(10))
if err != nil {
return err
}

case len(args) >= 1:
modelName = args[0]
}

modelSummary, err := getModelByName(modelName, models)
if err != nil {
return err
}

modelDetails, err := client.GetModelDetails(modelSummary.RegistryName, modelSummary.Name, modelSummary.Version)
if err != nil {
return err
}

modelPrinter := newModelPrinter(modelSummary, modelDetails, terminal)

err = modelPrinter.render()
if err != nil {
return err
}

return nil
},
}
return cmd
}

// getModelByName returns the model with the specified name, or an error if no such model exists within the given list.
func getModelByName(modelName string, models []*azure_models.ModelSummary) (*azure_models.ModelSummary, error) {
for _, model := range models {
if model.HasName(modelName) {
return model, nil
}
}
return nil, fmt.Errorf("the specified model name is not supported: %s", modelName)
}
33 changes: 23 additions & 10 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,37 +1,50 @@
module github.com/github/gh-models

go 1.22
go 1.22.5

toolchain go1.22.8

require (
github.com/AlecAivazis/survey/v2 v2.3.7
github.com/briandowns/spinner v1.23.1
github.com/cli/go-gh/v2 v2.9.0
github.com/spf13/cobra v1.8.0
github.com/cli/cli/v2 v2.58.0
github.com/cli/go-gh/v2 v2.10.0
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
golang.org/x/text v0.18.0
)

require (
github.com/alecthomas/chroma/v2 v2.8.0 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/aymerick/douceur v0.2.0 // indirect
github.com/charmbracelet/glamour v0.7.0 // indirect
github.com/charmbracelet/lipgloss v0.10.1-0.20240413172830-d0be07ea6b9c // indirect
github.com/charmbracelet/x/exp/term v0.0.0-20240425164147-ba2a9512b05f // indirect
github.com/cli/safeexec v1.0.0 // indirect
github.com/cli/safeexec v1.0.1 // indirect
github.com/cli/shurcooL-graphql v0.0.4 // indirect
github.com/fatih/color v1.7.0 // indirect
github.com/henvic/httpretty v0.0.6 // indirect
github.com/dlclark/regexp2 v1.4.0 // indirect
github.com/fatih/color v1.16.0 // indirect
github.com/gorilla/css v1.0.0 // indirect
github.com/henvic/httpretty v0.1.4 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/microcosm-cc/bluemonday v1.0.26 // indirect
github.com/muesli/reflow v0.3.0 // indirect
github.com/muesli/termenv v0.15.2 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/term v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
github.com/yuin/goldmark v1.5.4 // indirect
github.com/yuin/goldmark-emoji v1.0.2 // indirect
golang.org/x/net v0.27.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/term v0.24.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading