diff --git a/general/ai/cli.go b/general/ai/cli.go index b1dd74cfc..e813c87a9 100644 --- a/general/ai/cli.go +++ b/general/ai/cli.go @@ -3,7 +3,6 @@ package ai import ( "bufio" "bytes" - "encoding/json" "errors" "fmt" "github.com/jfrog/jfrog-cli-core/v2/utils/coreutils" @@ -22,11 +21,8 @@ import ( type ApiCommand string const ( - cliAiApiPath = "https://cli-ai-app.jfrog.info/" - apiPrefix = "api/" - questionApi ApiCommand = apiPrefix + "ask" - feedbackApi ApiCommand = apiPrefix + "feedback" - apiHeader = "X-JFrog-CLI-AI" + cliAiAskApiPath = "https://cli-ai-app.jfrog.info/api/ask" + apiHeader = "X-JFrog-CLI-AI" ) type QuestionBody struct { @@ -64,67 +60,30 @@ func HowCmd(c *cli.Context) error { } } fmt.Print("\n🤖 Generated command:\n ") - questionBody := QuestionBody{Question: question} - llmAnswer, err := askQuestion(questionBody) + llmAnswer, err := askQuestion(question) if err != nil { return err } - log.Output(coreutils.PrintLink(llmAnswer) + "\n") - - // Ask the user for feedback - feedback := FeedbackBody{QuestionBody: questionBody, LlmAnswer: llmAnswer} - feedback.getUserFeedback() - if err = sendFeedback(feedback); err != nil { - return err - } + log.Output(coreutils.PrintLink(llmAnswer)) log.Output("\n" + coreutils.PrintComment("-------------------") + "\n") } } -func (fb *FeedbackBody) getUserFeedback() { - fb.IsAccurate = coreutils.AskYesNo("Is the provided command accurate?", true) - if !fb.IsAccurate { - scanner := bufio.NewScanner(os.Stdin) - fmt.Print("Please provide the exact command you expected (Example: 'jf rt u ...'): ") - for { - scanner.Scan() - expectedAnswer := strings.TrimSpace(scanner.Text()) - if expectedAnswer != "" { - // If the user entered an expected answer, break and return - fb.ExpectedAnswer = expectedAnswer - return - } - } - } -} - -func askQuestion(question QuestionBody) (response string, err error) { - return sendRequestToCliAiServer(question, questionApi) -} - -func sendFeedback(feedback FeedbackBody) (err error) { - _, err = sendRequestToCliAiServer(feedback, feedbackApi) - return -} - -func sendRequestToCliAiServer(content interface{}, apiCommand ApiCommand) (response string, err error) { - contentBytes, err := json.Marshal(content) - if errorutils.CheckError(err) != nil { - return - } +func askQuestion(question string) (response string, err error) { client, err := httpclient.ClientBuilder().Build() if errorutils.CheckError(err) != nil { return } - req, err := http.NewRequest(http.MethodPost, cliAiApiPath+string(apiCommand), bytes.NewBuffer(contentBytes)) + req, err := http.NewRequest(http.MethodPost, cliAiAskApiPath, bytes.NewBufferString(question)) if errorutils.CheckError(err) != nil { return } - req.Header.Set("Content-Type", "application/json") + req.Header.Set("Content-Type", "text/plain") req.Header.Set(apiHeader, "true") log.Debug(fmt.Sprintf("Sending HTTP %s request to: %s", req.Method, req.URL)) resp, err := client.GetClient().Do(req) - if errorutils.CheckError(err) != nil { + if err != nil { + err = errorutils.CheckErrorf("CLI-AI server is not available. Please check your network or try again later.") return } if resp == nil { @@ -134,28 +93,25 @@ func sendRequestToCliAiServer(content interface{}, apiCommand ApiCommand) (respo if err = errorutils.CheckResponseStatus(resp, http.StatusOK); err != nil { switch resp.StatusCode { case http.StatusInternalServerError: - err = errorutils.CheckErrorf("AI model Endpoint is not available. Please try again later.") - case http.StatusNotFound: - err = errorutils.CheckErrorf("CLI-AI app server is not available. Note that the this command is supported while inside JFrog's internal network only.\n" + err.Error()) + err = errorutils.CheckErrorf("CLI-AI model endpoint is not available. Please try again later.") case http.StatusNotAcceptable: err = errorutils.CheckErrorf("CLI-AI app server is not available. Please try again later.") default: + err = errorutils.CheckErrorf("CLI-AI server is not available. Please check your network or try again later. Note that the this command is supported while inside JFrog's internal network only.\n" + err.Error()) return } } - if apiCommand == questionApi { - defer func() { - if resp.Body != nil { - err = errors.Join(err, errorutils.CheckError(resp.Body.Close())) - } - }() - var body []byte - // Limit size of response body to 10MB - body, err = io.ReadAll(io.LimitReader(resp.Body, 10*utils.SizeMiB)) - if errorutils.CheckError(err) != nil { - return + defer func() { + if resp.Body != nil { + err = errors.Join(err, errorutils.CheckError(resp.Body.Close())) } - response = strings.TrimSpace(string(body)) + }() + var body []byte + // Limit size of response body to 10MB + body, err = io.ReadAll(io.LimitReader(resp.Body, 10*utils.SizeMiB)) + if errorutils.CheckError(err) != nil { + return } + response = strings.TrimSpace(string(body)) return } diff --git a/general/token/cli.go b/general/token/cli.go index bb35fd983..47b7bb5f2 100644 --- a/general/token/cli.go +++ b/general/token/cli.go @@ -73,7 +73,7 @@ func createPlatformDetailsByFlags(c *cli.Context) (*coreConfig.ServerDetails, er return nil, err } if platformDetails.Url == "" { - return nil, errors.New("platform URL is mandatory for access token creation") + return nil, errors.New("JFrog Platform URL is mandatory for access token creation") } return platformDetails, nil } diff --git a/go.mod b/go.mod index 67a5e0132..b32e4b308 100644 --- a/go.mod +++ b/go.mod @@ -172,7 +172,7 @@ require ( replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20240811125027-368d22cd5cc3 -// replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20240804121253-32ba23f22ade +replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20240806162439-01bb7dcd43fc // replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go v1.8.9-0.20240804091815-7407ceb49077 diff --git a/go.sum b/go.sum index 026a425ee..c637e8e2a 100644 --- a/go.sum +++ b/go.sum @@ -952,8 +952,8 @@ github.com/jfrog/jfrog-cli-platform-services v1.3.0 h1:IblSDZFBjL7WLRi37Ni2DmHrX github.com/jfrog/jfrog-cli-platform-services v1.3.0/go.mod h1:Ky4SDXuMeaiNP/5zMT1YSzIuXG+cNYYOl8BaEA7Awbc= github.com/jfrog/jfrog-cli-security v1.6.4 h1:GzKgICdgxgaMQNHHACrURcThjP48lh2p0tWiYzWQGuY= github.com/jfrog/jfrog-cli-security v1.6.4/go.mod h1:ViFPXeznp/e73yCYu3aogHJbIYt6E32SujbppRoeem8= -github.com/jfrog/jfrog-client-go v1.43.2 h1:NLSTTSFUkrNiSYs8rpRW7/sd6gDTPOi/eMVkGEarXq0= -github.com/jfrog/jfrog-client-go v1.43.2/go.mod h1:JUevXnjHbGL0MIIPs48L/axJMW/q4ioWMR1e1NuVn8w= +github.com/jfrog/jfrog-client-go v1.28.1-0.20240806162439-01bb7dcd43fc h1:Io6G3dCqFK2LKq0FyZyaX2LE83CXnDNAJh6ww+6dMGg= +github.com/jfrog/jfrog-client-go v1.28.1-0.20240806162439-01bb7dcd43fc/go.mod h1:JUevXnjHbGL0MIIPs48L/axJMW/q4ioWMR1e1NuVn8w= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jszwec/csvutil v1.10.0 h1:upMDUxhQKqZ5ZDCs/wy+8Kib8rZR8I8lOR34yJkdqhI= diff --git a/lifecycle/cli.go b/lifecycle/cli.go index b47731934..4921cff23 100644 --- a/lifecycle/cli.go +++ b/lifecycle/cli.go @@ -371,7 +371,7 @@ func createLifecycleDetailsByFlags(c *cli.Context) (*coreConfig.ServerDetails, e return nil, err } if lcDetails.Url == "" { - return nil, errors.New("platform URL is mandatory for lifecycle commands") + return nil, errors.New("JFrog Platform URL is mandatory for lifecycle commands") } PlatformToLifecycleUrls(lcDetails) return lcDetails, nil