-
Notifications
You must be signed in to change notification settings - Fork 16
Add gh models view command
#6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
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 2ac9122
Prompt to select a model if none specified
cheshire137 08b184a
Add util.GetValidModelName
cheshire137 5ebf021
Bail early when specified model name is invalid
cheshire137 1e92fd9
Bail early when provided model name for 'run' is invalid
cheshire137 f9b7694
Replace with ValidateModelName
cheshire137 c873994
Replace with GetModelByName, output friendly name
cheshire137 07858b8
Pull out LightGrayUnderline shared color
cheshire137 8602571
Pull out modelPrinter type
cheshire137 b995626
Show publisher and summary fields
cheshire137 7aa576e
Pull out azureAiStudioURL constant
cheshire137 d75afc9
Start on client GetModelDetails
cheshire137 02ca397
Get the version and registry name, too
cheshire137 a042eb6
Dump out model details at the end
cheshire137 4f833dc
Add modelCatalogDetailsResponse type
cheshire137 0a56b20
Display model description from details
cheshire137 bb9e140
Output license details with 'view' command
cheshire137 509238f
Merge branch 'main' into view-cmd
cheshire137 584ac6e
Drop centralized colors
cheshire137 fdd8d03
Move getModelByName into view package
cheshire137 c924fe4
Add HasName to ModelSummary
cheshire137 287062a
Display model notes, add blank line between multi-line fields
cheshire137 2606848
Include tags in view output
cheshire137 4ecefd9
Don't output labels for blank values
cheshire137 c1da574
Display supported inputs and outputs
cheshire137 73fd787
Display 'evaluation' field
cheshire137 3600097
Use snake case for JSON fields like our other external-facing types
cheshire137 b761cee
Display supported languages
cheshire137 adfefec
Display context max tokens
cheshire137 d2ccb20
Display rate limit tier
cheshire137 0e61970
Do some Markdown processing on multi-line fields
cheshire137 c62a6cc
Don't truncate list of languages
cheshire137 4c441d9
Reduce whitespace in output
cheshire137 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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)) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | ||
| ) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice