Files
commandkit/integrations/ckprompt/validation_command.go

109 lines
4.5 KiB
Go

package ckprompt
import (
"errors"
"fmt"
commandkit "go.maximumdirect.net/commandkit"
)
type validationCommandInput[I any] struct {
promptID string
request ValidationRequest
execution ExecutionInput
resources ResourceInput
inputs PromptInputs
captured commandkit.FlagValues[I]
selected I
}
type requestValidationReport struct {
PromptID string `json:"prompt_id"`
Valid bool `json:"valid"`
}
func newValidationCommand[I, S any](suite Suite[I, S]) commandkit.Command {
flags := commandkit.CaptureFlags(suite.Selectors, func(input **validationCommandInput[I]) *commandkit.FlagValues[I] {
if input == nil || *input == nil {
return nil
}
return &(*input).captured
})
flags = append(flags,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Configuration input path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
func(input **validationCommandInput[I], value commandkit.Supplied[string]) {
(*input).request.Selection.Config = value
}),
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Configuration overlay path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
func(input **validationCommandInput[I], value commandkit.Supplied[string]) {
(*input).request.Selection.Overlay = value
}),
)
resources := NewResourceFlags(func(input **validationCommandInput[I]) *ResourceInput { return &(*input).resources })
execution := NewExecutionFlags(func(input **validationCommandInput[I]) *ExecutionInput { return &(*input).execution })
inputs := NewPromptInputFlags(func(input **validationCommandInput[I]) *PromptInputs { return &(*input).inputs })
flags = append(flags, resources.Profile, resources.SessionID, inputs.Variable, inputs.Text, inputs.File)
flags = append(flags, execution.All()...)
return commandkit.NewCommand(commandkit.CommandSpec[*validationCommandInput[I]]{
Name: "validate",
Summary: "Validate a concrete PromptKit request without executing it.",
NewInput: func() *validationCommandInput[I] {
return &validationCommandInput[I]{}
},
Flags: flags,
Arguments: []commandkit.Argument[*validationCommandInput[I]]{
commandkit.ValueArgument(commandkit.ArgumentMeta{Name: "id", Usage: "Prompt ID."}, true, parseDefinitionString,
func(input **validationCommandInput[I], value commandkit.Supplied[string]) {
(*input).promptID = value.Value
(*input).request.Request.PromptID = value.Value
}),
},
CheckInput: func(input *validationCommandInput[I]) error {
if input == nil {
return errors.New("PromptKit validation input must not be nil")
}
input.request.Request.ProfileID = input.resources.Profile.Value
input.request.Request.SessionID = input.resources.SessionID.Value
input.request.Request.Vars = input.inputs.Vars
input.request.Request.Inputs = input.inputs.Inputs
input.request.Request.Execution = input.execution.Execution
input.request.Request.TransientRetries = input.execution.TransientRetries
selected, err := prepareSuiteInput(suite, input.request.Selection, input.captured)
if err != nil {
return err
}
input.selected = selected
return nil
},
Run: func(invocation commandkit.Invocation, input *validationCommandInput[I]) commandkit.Outcome {
return runRequestValidation(invocation, suite, input)
},
})
}
func runRequestValidation[I, S any](invocation commandkit.Invocation, suite Suite[I, S], input *validationCommandInput[I]) commandkit.Outcome {
if err := promptKitContextError(invocation.Context); err != nil {
return definitionFailure("PromptKit request validation was canceled.", commandkit.Explanation{}, err)
}
var state S
if suite.NewState != nil {
state = suite.NewState()
}
if err := promptKitContextError(invocation.Context); err != nil {
return definitionFailure("PromptKit request validation was canceled.", commandkit.Explanation{}, err)
}
acquired, err := suite.ValidateRequest(invocation.Context, input.request, input.selected, state)
queuePromptDiagnostics(invocation.Reporter(), acquired.Diagnostics)
if err != nil {
return definitionFailure(fmt.Sprintf("Unable to validate the PromptKit request for prompt %q.", input.promptID), acquired.Explanation, err)
}
if err := promptKitContextError(invocation.Context); err != nil {
return definitionFailure(fmt.Sprintf("Validation of the PromptKit request for prompt %q was canceled.", input.promptID), acquired.Explanation, err)
}
_ = invocation.Reporter().Report(commandkit.Report{Value: requestValidationReport{PromptID: input.promptID, Valid: true}})
return commandkit.Success()
}