Add opt-in configuration overrides

This commit is contained in:
2026-11-07 04:39:34 +00:00
parent 85ae55bf42
commit aeb70e5873
22 changed files with 238 additions and 35 deletions

View File

@@ -150,14 +150,14 @@ func TestWithSmokeTestingForwardsAuthoritativeNativeRequestAndRetainsReport(t *t
suite := WithSmokeTesting(Suite[input, state]{},
func(ctx context.Context, selection ckconfig.Selection, gotInput input, gotState state) (*promptkit.Engine, error) {
loaderCalls++
if ctx.Value(contextKey{}) != "smoke invocation" || selection != wantSelection || gotInput != wantInput || gotState != wantState {
if ctx.Value(contextKey{}) != "smoke invocation" || !reflect.DeepEqual(selection, wantSelection) || gotInput != wantInput || gotState != wantState {
t.Errorf("loader args = ctx=%v selection=%#v input=%#v state=%#v", ctx.Value(contextKey{}), selection, gotInput, gotState)
}
return engine, nil
},
func(ctx context.Context, request SmokeRequest, gotInput input, gotState state) (promptkit.SmokeTestRequest, error) {
builderCalls++
if ctx.Value(contextKey{}) != "smoke invocation" || request.Selection != wantSelection || request.Request.Kind != promptkit.SmokeTestAuthentication || gotInput != wantInput || gotState != wantState {
if ctx.Value(contextKey{}) != "smoke invocation" || !reflect.DeepEqual(request.Selection, wantSelection) || request.Request.Kind != promptkit.SmokeTestAuthentication || gotInput != wantInput || gotState != wantState {
t.Errorf("builder args = ctx=%v request=%#v input=%#v state=%#v", ctx.Value(contextKey{}), request, gotInput, gotState)
}
return built, nil
@@ -431,7 +431,7 @@ func TestConfigScopeCompareUsesNativeDiffAndLoadsBothEqualSelections(t *testing.
if !reflect.DeepEqual(got.Value, want) {
t.Fatalf("adapter differences = %#v, want native PromptKit result %#v", got.Value, want)
}
if len(calls) != 2 || calls[0].selection != selection || calls[1].selection != selection || calls[0].input.label != "before" || calls[1].input.label != "after" || calls[0].state != state || calls[1].state != state {
if len(calls) != 2 || !reflect.DeepEqual(calls[0].selection, selection) || !reflect.DeepEqual(calls[1].selection, selection) || calls[0].input.label != "before" || calls[1].input.label != "after" || calls[0].state != state || calls[1].state != state {
t.Fatalf("loader calls = %#v", calls)
}
}
@@ -659,7 +659,7 @@ func TestFromEngineListsNativeCatalogsWithInvocationValues(t *testing.T) {
loaderCalls := 0
suite := FromEngine(func(ctx context.Context, selection ckconfig.Selection, gotInput input, gotState state) (*promptkit.Engine, error) {
loaderCalls++
if ctx.Value(contextKey{}) != "catalog invocation" || selection != wantSelection || gotInput != wantInput || gotState != wantState {
if ctx.Value(contextKey{}) != "catalog invocation" || !reflect.DeepEqual(selection, wantSelection) || gotInput != wantInput || gotState != wantState {
t.Errorf("loader args = ctx=%v selection=%#v input=%#v state=%#v", ctx.Value(contextKey{}), selection, gotInput, gotState)
}
return engine, nil

View File

@@ -32,8 +32,9 @@ type inspectionInput struct {
}
type applicationCacheKey struct {
selection ckconfig.Selection
campaign commandkit.Supplied[string]
config commandkit.Supplied[string]
overlay commandkit.Supplied[string]
campaign commandkit.Supplied[string]
}
// runCache belongs to one invocation and is shared only where the application
@@ -80,7 +81,7 @@ func loadApplicationConfig(ctx context.Context, selection ckconfig.Selection, in
if input != nil {
campaignInput = input.Campaign
}
key := applicationCacheKey{selection: selection, campaign: campaignInput}
key := applicationCacheKey{config: selection.Config, overlay: selection.Overlay, campaign: campaignInput}
if cache != nil {
if cached, ok := cache.applications[key]; ok {
return cached, nil

View File

@@ -266,7 +266,7 @@ func TestBuildValidationRequestDefaultsOnlyAbsentVariables(t *testing.T) {
if !reflect.DeepEqual(got.Inputs, inputs) || !reflect.DeepEqual(seed.Request.Vars, explicit) {
t.Fatalf("seed bindings changed: built=%#v seed=%#v", got.Inputs, explicit)
}
key := applicationCacheKey{selection: seed.Selection, campaign: input.Campaign}
key := applicationCacheKey{config: seed.Selection.Config, overlay: seed.Selection.Overlay, campaign: input.Campaign}
cached := cache.applications[key]
if cached == nil {
t.Fatal("builder did not load application configuration into invocation state")

View File

@@ -49,7 +49,7 @@ func TestSmokeTestCommandRetainsSingletonValuesAndResetsInvocations(t *testing.T
Overlay: commandkit.Supplied[string]{Value: "final-overlay.yml", Set: true},
}
got := requests[0]
if got.selection != wantSelection || got.input.campaign != "final" || got.request.BackendID != "final-backend" || got.request.PromptID != "final-prompt" || got.request.ProfileID != "final-profile" {
if !reflect.DeepEqual(got.selection, wantSelection) || got.input.campaign != "final" || got.request.BackendID != "final-backend" || got.request.PromptID != "final-prompt" || got.request.ProfileID != "final-profile" {
t.Fatalf("last supplied values = %#v", got)
}
if got.request.Execution == nil || got.request.Execution.Model != "final-model" || got.request.Execution.Temperature == nil || *got.request.Execution.Temperature != 0 || got.request.TransientRetries == nil || *got.request.TransientRetries != 0 {

View File

@@ -4,6 +4,7 @@ import (
"context"
"errors"
"io"
"reflect"
"strings"
"testing"
"testing/fstest"
@@ -61,7 +62,7 @@ func TestWithRequestValidationPreservesSuiteAndValidatesSeedWithoutBuilder(t *te
loaderCalls := 0
suite = WithRequestValidation(suite, func(gotContext context.Context, gotSelection ckconfig.Selection, gotInput input, gotState state) (*promptkit.Engine, error) {
loaderCalls++
if gotContext != ctx || gotContext.Value(contextKey{}) != "invocation" || gotSelection != selection || gotInput.value != "input" || gotState.value != "state" {
if gotContext != ctx || gotContext.Value(contextKey{}) != "invocation" || !reflect.DeepEqual(gotSelection, selection) || gotInput.value != "input" || gotState.value != "state" {
t.Errorf("loader args = (%v, %#v, %#v, %#v)", gotContext, gotSelection, gotInput, gotState)
}
return engine, nil
@@ -138,7 +139,7 @@ func TestWithRequestValidationDelegatesNativeOutcomesWithoutModelCalls(t *testin
engine := validationTestEngine(t, adapterPrompt, promptkit.WithLLMClient(client))
selection := ckconfig.Selection{Config: commandkit.Supplied[string]{Value: "selected.yml", Set: true}}
suite := WithRequestValidation(Suite[struct{}, struct{}]{}, func(_ context.Context, gotSelection ckconfig.Selection, _, _ struct{}) (*promptkit.Engine, error) {
if gotSelection != selection {
if !reflect.DeepEqual(gotSelection, selection) {
t.Errorf("loader selection = %#v, want %#v", gotSelection, selection)
}
return engine, nil
@@ -190,13 +191,13 @@ func TestWithRequestValidationBuilderOutputReachesNativeValidation(t *testing.T)
builderCalls, loaderCalls := 0, 0
suite := WithRequestValidation(Suite[input, state]{}, func(gotContext context.Context, gotSelection ckconfig.Selection, gotInput input, gotState state) (*promptkit.Engine, error) {
loaderCalls++
if gotContext != ctx || gotContext.Value(contextKey{}) != "validation invocation" || gotSelection != selection || gotInput != wantInput || gotState != wantState {
if gotContext != ctx || gotContext.Value(contextKey{}) != "validation invocation" || !reflect.DeepEqual(gotSelection, selection) || gotInput != wantInput || gotState != wantState {
t.Errorf("loader args = (%v, %#v, %#v, %#v)", gotContext, gotSelection, gotInput, gotState)
}
return engine, nil
}, func(gotContext context.Context, request ValidationRequest, gotInput input, gotState state) (promptkit.RunRequest, error) {
builderCalls++
if gotContext != ctx || gotContext.Value(contextKey{}) != "validation invocation" || request.Selection != selection || request.Request.PromptID != seed.PromptID || request.Request.Vars["topic"] != "seed topic" || gotInput != wantInput || gotState != wantState {
if gotContext != ctx || gotContext.Value(contextKey{}) != "validation invocation" || !reflect.DeepEqual(request.Selection, selection) || request.Request.PromptID != seed.PromptID || request.Request.Vars["topic"] != "seed topic" || gotInput != wantInput || gotState != wantState {
t.Errorf("builder args = (%v, %#v, %#v, %#v)", gotContext, request, gotInput, gotState)
}
built := request.Request

View File

@@ -34,7 +34,7 @@ func TestValidationCommandComposesWithRequirementsShow(t *testing.T) {
NewState: func() state { return state{sequence: 1} },
Selectors: []commandkit.Flag[input]{campaignFlag},
CheckInput: func(selection ckconfig.Selection, value input) error {
if selection != wantSelection || !reflect.DeepEqual(value, wantInput) {
if !reflect.DeepEqual(selection, wantSelection) || !reflect.DeepEqual(value, wantInput) {
t.Errorf("checked input = (%#v, %#v)", selection, value)
}
return nil
@@ -70,7 +70,7 @@ func TestValidationCommandComposesWithRequirementsShow(t *testing.T) {
if outcome.Kind != commandkit.OutcomeSuccess || outcome.Status != 0 || validateCalls != 1 {
t.Fatalf("validation outcome = (%#v, %q), calls=%d", outcome, output.String(), validateCalls)
}
if received.Selection != wantSelection || received.Request.PromptID != "briefing" || received.Request.ProfileID != "editorial" || received.Request.SessionID != "session-1" {
if !reflect.DeepEqual(received.Selection, wantSelection) || received.Request.PromptID != "briefing" || received.Request.ProfileID != "editorial" || received.Request.SessionID != "session-1" {
t.Errorf("validation request = %#v", received)
}
if received.Request.Vars["topic"] != "roadmap" || len(received.Request.Vars) != 1 {