Skip to content

Commit

Permalink
feat: reprompt support (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
sozercan authored Apr 12, 2023
1 parent a117045 commit 4df7767
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 57 deletions.
65 changes: 35 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ If `AZURE_OPENAI_ENDPOINT` variable is set, then it will use the Azure OpenAI Se

## Examples

Creating objects with specific values:
### Creating objects with specific values

```shell
$ kubectl ai "create an nginx deployment with 3 replicas"
Expand All @@ -74,20 +74,25 @@ spec:
image: nginx:1.7.9
ports:
- containerPort: 80
EOF
Use the arrow keys to navigate: ↓ ↑ → ←
? Would you like to apply this? [Apply/Don't Apply]:
? Would you like to apply this? [Reprompt/Apply/Don't Apply]:
+ Reprompt
▸ Apply
Don't Apply
```
### Reprompt to refine your prompt
```shell
$ kubectl ai "scale nginx-deployment to 5 replicas"
...
Reprompt: update to 5 replicas and port 8080
✨ Attempting to apply the following manifest:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 5
selector:
Expand All @@ -102,35 +107,15 @@ spec:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
EOF
- containerPort: 8080
Use the arrow keys to navigate: ↓ ↑ → ←
? Would you like to apply this? [Apply/Don't Apply]:
? Would you like to apply this? [Reprompt/Apply/Don't Apply]:
+ Reprompt
▸ Apply
Don't Apply
```
> Please note that the plugin does not know the current state of the cluster (yet?), so it will always generate the full manifest.
Optional `--require-confirmation` flag:
```shell
$ kubectl ai "create a service with type LoadBalancer with selector as 'app:nginx'" --require-confirmation=false
✨ Attempting to apply the following manifest:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: LoadBalancer
```
Multiple objects:
### Multiple objects
```shell
$ kubectl ai "create a foo namespace then create nginx pod in that namespace"
Expand All @@ -149,13 +134,33 @@ spec:
containers:
- name: nginx
image: nginx:latest
EOF
Use the arrow keys to navigate: ↓ ↑ → ←
? Would you like to apply this? [Apply/Don't Apply]:
? Would you like to apply this? [Reprompt/Apply/Don't Apply]:
+ Reprompt
▸ Apply
Don't Apply
```
### Optional `--require-confirmation` flag
```shell
$ kubectl ai "create a service with type LoadBalancer with selector as 'app:nginx'" --require-confirmation=false
✨ Attempting to apply the following manifest:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: LoadBalancer
```
> Please note that the plugin does not know the current state of the cluster (yet?), so it will always generate the full manifest.
## Acknowledgements and Credits
Thanks to @simongottschlag for their work on Azure OpenAI fork in https://github.com/simongottschlag/azure-openai-gpt-slack-bot
Expand Down
71 changes: 44 additions & 27 deletions cmd/cli/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@ import (
"k8s.io/cli-runtime/pkg/genericclioptions"
)

const version = "0.0.3"
const (
version = "0.0.7"

apply = "Apply"
dontApply = "Don't Apply"
reprompt = "Reprompt"
)

var (
kubernetesConfigFlags *genericclioptions.ConfigFlags
Expand Down Expand Up @@ -75,39 +81,50 @@ func run(args []string) error {
return err
}

completion, err := gptCompletion(ctx, oaiClients, args, *openAIDeploymentName)
if err != nil {
return err
}

text := fmt.Sprintf("✨ Attempting to apply the following manifest: %s", completion)
fmt.Println(text)
var action, completion string
for action != apply {
args = append(args, action)
completion, err = gptCompletion(ctx, oaiClients, args, *openAIDeploymentName)
if err != nil {
return err
}

conf, err := getUserConfirmation()
if err != nil {
return err
}
text := fmt.Sprintf("✨ Attempting to apply the following manifest:\n%s", completion)
fmt.Println(text)

if conf {
if err = applyManifest(completion); err != nil {
action, err = userActionPrompt()
if err != nil {
return err
}

if action == dontApply {
return nil
}
}
return nil

return applyManifest(completion)
}

func getUserConfirmation() (bool, error) {
result := "Apply"
func userActionPrompt() (string, error) {
// if require confirmation is not set, immediately return apply
if !*requireConfirmation {
return apply, nil
}

var result string
var err error
if *requireConfirmation {
prompt := promptui.Select{
Label: "Would you like to apply this? [Apply/Don't Apply]",
Items: []string{"Apply", "Don't Apply"},
}
_, result, err = prompt.Run()
if err != nil {
return false, err
}
items := []string{apply, dontApply}
label := fmt.Sprintf("Would you like to apply this? [%s/%s/%s]", reprompt, apply, dontApply)

prompt := promptui.SelectWithAdd{
Label: label,
Items: items,
AddLabel: reprompt,
}
return result == "Apply", nil
_, result, err = prompt.Run()
if err != nil {
return dontApply, err
}

return result, nil
}

0 comments on commit 4df7767

Please sign in to comment.