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() }