Files

74 lines
3.2 KiB
Go

package ckprompt
import (
"context"
"errors"
"fmt"
commandkit "gitea.maximumdirect.net/eric/CommandKit"
"gitea.maximumdirect.net/eric/CommandKit/integrations/ckconfig"
promptkit "gitea.maximumdirect.net/eric/promptkit"
)
// SmokeRequest pairs the configuration selection with the seed request for one
// concrete PromptKit smoke-test operation. It is passed to the optional
// builder and the Suite.SmokeTest callback.
type SmokeRequest struct {
// Selection identifies the configuration sources used to load the engine.
Selection ckconfig.Selection
// Request contains the native smoke-test operation and its selected inputs.
Request promptkit.SmokeTestRequest
}
// WithSmokeTesting attaches PromptKit-backed smoke testing to suite while
// preserving its other capabilities and retained issues. The optional builder
// runs before engine loading and receives the seed request, input, state, and
// invocation context. Its complete returned request is passed to PromptKit;
// without a builder, the seed is forwarded unchanged. Reports and errors from
// PromptKit are both retained. A nil loader is kept as a suite wiring issue and
// does not install a smoke-test callback. The callback also retains independent
// engine diagnostics and terminal context with the report and error. Native
// operation errors supply terminal explanations when structured context is absent.
func WithSmokeTesting[I, S any](
suite Suite[I, S],
load func(context.Context, ckconfig.Selection, I, S) (*promptkit.Engine, error),
build func(context.Context, SmokeRequest, I, S) (promptkit.SmokeTestRequest, error),
) Suite[I, S] {
if load == nil {
issues := append([]error(nil), suite.issues...)
suite.issues = append(issues, errors.New("PromptKit engine loader is nil"))
return suite
}
suite.SmokeTest = func(ctx context.Context, request SmokeRequest, input I, state S) (commandkit.Acquired[*promptkit.SmokeTestReport], error) {
if err := promptKitContextError(ctx); err != nil {
return commandkit.Acquired[*promptkit.SmokeTestReport]{}, fmt.Errorf("PromptKit smoke test before building: %w", err)
}
concreteRequest := request.Request
if build != nil {
built, err := build(ctx, request, input, state)
if err != nil {
return commandkit.Acquired[*promptkit.SmokeTestReport]{}, err
}
concreteRequest = built
}
if err := promptKitContextError(ctx); err != nil {
return commandkit.Acquired[*promptkit.SmokeTestReport]{}, fmt.Errorf("PromptKit smoke test after building: %w", err)
}
engine, _, messages, err := loadPromptKitEngine(ctx, request.Selection, input, state, "", load)
if err != nil {
return commandkit.Acquired[*promptkit.SmokeTestReport]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
}
if err := promptKitContextError(ctx); err != nil {
return commandkit.Acquired[*promptkit.SmokeTestReport]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, fmt.Errorf("PromptKit smoke test before native operation: %w", err)
}
report, err := engine.SmokeTest(ctx, concreteRequest)
messages = messages.withOperationError(err)
return commandkit.Acquired[*promptkit.SmokeTestReport]{Value: report, Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
}
return suite
}