Skip to content

Commit

Permalink
Update dependencies (#2681)
Browse files Browse the repository at this point in the history
  • Loading branch information
sverdlov93 authored Sep 9, 2024
1 parent fa152c0 commit ee4857b
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 19 deletions.
101 changes: 90 additions & 11 deletions general/ai/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
"github.com/jfrog/jfrog-cli/utils/cliutils"
"github.com/jfrog/jfrog-client-go/artifactory/services/utils"
"github.com/jfrog/jfrog-client-go/http/httpclient"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
"github.com/jfrog/jfrog-client-go/utils/log"
"github.com/manifoldco/promptui"
"github.com/urfave/cli"
"io"
"net/http"
Expand All @@ -22,13 +24,16 @@ import (
type ApiCommand string

const (
cliAiAskApiPath = "https://cli-ai-app.jfrog.info/api/ask"
apiHeader = "X-JFrog-CLI-AI"
cliAiAppApiUrl = "https://cli-ai-app.jfrog.info/api/"
askRateLimitHeader = "X-JFrog-CLI-AI"
)

type QuestionBody struct {
Question string `json:"question"`
}
type ApiType string

const (
ask ApiType = "ask"
feedback ApiType = "feedback"
)

func HowCmd(c *cli.Context) error {
if show, err := cliutils.ShowCmdHelpIfNeeded(c, c.Args()); show || err != nil {
Expand All @@ -37,7 +42,7 @@ func HowCmd(c *cli.Context) error {
if c.NArg() > 0 {
return cliutils.WrongNumberOfArgumentsHandler(c)
}
log.Output(coreutils.PrintTitle("This AI-based interface converts your natural language inputs into fully functional JFrog CLI commands.\n" +
log.Output(coreutils.PrintLink("This AI-based interface converts your natural language inputs into fully functional JFrog CLI commands.\n" +
"NOTE: This is an experimental version and it supports mostly Artifactory and Xray commands.\n"))

for {
Expand All @@ -53,31 +58,99 @@ func HowCmd(c *cli.Context) error {
break
}
}
fmt.Print("\n🤖 Generated command:\n ")
fmt.Print("\n🤖 Generated command:\n")
llmAnswer, err := askQuestion(question)
if err != nil {
return err
}
log.Output(coreutils.PrintLink(llmAnswer))
// Print the generated command within a styled table frame.
// TODO: Use this from jfrog-cli-core
PrintMessageInsideFrame(coreutils.PrintBoldTitle(llmAnswer), " ")

log.Output()
if err = sendFeedback(); err != nil {
return err
}

log.Output("\n" + coreutils.PrintComment("-------------------") + "\n")
}
}

func PrintMessageInsideFrame(message, marginLeft string) {
tableWriter := table.NewWriter()
tableWriter.SetOutputMirror(os.Stdout)
if log.IsStdOutTerminal() {
tableWriter.SetStyle(table.StyleLight)
}
// Set padding left for the whole frame (for example, " ").
tableWriter.Style().Box.Left = marginLeft + tableWriter.Style().Box.Left
tableWriter.Style().Box.TopLeft = marginLeft + tableWriter.Style().Box.TopLeft
tableWriter.Style().Box.BottomLeft = marginLeft + tableWriter.Style().Box.BottomLeft
// Remove emojis from non-supported terminals
tableWriter.AppendRow(table.Row{message})
tableWriter.Render()
}

type questionBody struct {
Question string `json:"question"`
}

func askQuestion(question string) (response string, err error) {
contentBytes, err := json.Marshal(QuestionBody{Question: question})
return sendRestAPI(ask, questionBody{Question: question})
}

type feedbackBody struct {
IsGoodResponse bool `json:"is_good_response"`
}

func sendFeedback() (err error) {
isGoodResponse, err := getUserFeedback()
if err != nil {
return err
}
_, err = sendRestAPI(feedback, feedbackBody{IsGoodResponse: isGoodResponse})
return err
}

func getUserFeedback() (bool, error) {
// Customize the template to place the options on the same line as the question
templates := &promptui.SelectTemplates{
Label: "{{ . }}",
Active: "👉 {{ . | cyan }}",
Inactive: " {{ . }}",
}

prompt := promptui.Select{
Label: "⭐ Rate this response:",
Items: []string{"👍 Good response!", "👎 Could be better..."},
Templates: templates,
HideHelp: true,
HideSelected: true,
}
selected, _, err := prompt.Run()
if err != nil {
return false, err
}
return selected == 0, nil
}

func sendRestAPI(apiType ApiType, content interface{}) (response string, err error) {
contentBytes, err := json.Marshal(content)
if errorutils.CheckError(err) != nil {
return
}
client, err := httpclient.ClientBuilder().Build()
if errorutils.CheckError(err) != nil {
return
}
req, err := http.NewRequest(http.MethodPost, cliAiAskApiPath, bytes.NewBuffer(contentBytes))
req, err := http.NewRequest(http.MethodPost, cliAiAppApiUrl+string(apiType), bytes.NewBuffer(contentBytes))
if errorutils.CheckError(err) != nil {
return
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set(apiHeader, "true")
if apiType == ask {
req.Header.Set(askRateLimitHeader, "true")
}
log.Debug(fmt.Sprintf("Sending HTTP %s request to: %s", req.Method, req.URL))
resp, err := client.GetClient().Do(req)
if err != nil {
Expand All @@ -100,6 +173,12 @@ func askQuestion(question string) (response string, err error) {
}
return
}

if apiType == feedback {
// If the API is feedback, no response is expected
return
}

defer func() {
if resp.Body != nil {
err = errors.Join(err, errorutils.CheckError(resp.Body.Close()))
Expand Down
7 changes: 3 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/jfrog/jfrog-cli

go 1.22.3
go 1.22.6

replace (
// Should not be updated to 0.2.6 due to a bug (https://github.com/jfrog/jfrog-cli-core/pull/372)
Expand All @@ -13,7 +13,7 @@ replace (
require (
github.com/agnivade/levenshtein v1.1.1
github.com/buger/jsonparser v1.1.1
github.com/docker/docker v27.1.2+incompatible
github.com/docker/docker v27.2.0+incompatible
github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1
github.com/jfrog/archiver/v3 v3.6.1
github.com/jfrog/build-info-go v1.9.35
Expand All @@ -24,6 +24,7 @@ require (
github.com/jfrog/jfrog-cli-security v1.8.0
github.com/jfrog/jfrog-client-go v1.46.1
github.com/jszwec/csvutil v1.10.0
github.com/manifoldco/promptui v0.9.0
github.com/stretchr/testify v1.9.0
github.com/testcontainers/testcontainers-go v0.33.0
github.com/urfave/cli v1.22.15
Expand Down Expand Up @@ -59,7 +60,6 @@ require (
github.com/docker/go-units v0.5.0 // indirect
github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/fatih/color v1.17.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/forPelevin/gomoji v1.2.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
Expand Down Expand Up @@ -94,7 +94,6 @@ require (
github.com/ktrysmt/go-bitbucket v0.9.73 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/manifoldco/promptui v0.9.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.16 // indirect
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -707,8 +707,8 @@ github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/docker v27.1.2+incompatible h1:AhGzR1xaQIy53qCkxARaFluI00WPGtXn0AJuoQsVYTY=
github.com/docker/docker v27.1.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v27.2.0+incompatible h1:Rk9nIVdfH3+Vz4cyI/uhbINhEZ/oLmc+CBXmH6fbNk4=
github.com/docker/docker v27.2.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
Expand Down Expand Up @@ -737,8 +737,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo=
github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w=
github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss=
github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
Expand Down

0 comments on commit ee4857b

Please sign in to comment.