Transfer owned provider settings during resolution

This commit is contained in:
2026-11-05 20:09:17 +00:00
parent 88725e79ab
commit c5f3de13f3
6 changed files with 37 additions and 22 deletions

View File

@@ -326,6 +326,12 @@ null/empty values, and construction errors without pinning deleted copy-error br
## Stage 12: Transfer Accepted Provider Maps Through Internal Resolution
**Completed:** Internal selection transfers owned provider maps without repeat
copies, preserving empty-map inheritance and nil projections; public override
validation and outward detachment remain. Go 1.27.3 `go test ./internal/usecase
./internal/configuration . -run 'Target|Profile|Override|Smoke|Provider|ExtraParams'`
passed.
**Finding:** 5; preserve 8. **Files:** `internal/usecase/runner.go`,
`profile_inspection.go`, `smoke_selection.go`, related ownership tests.

View File

@@ -7,7 +7,6 @@ import (
"strings"
"go.maximumdirect.net/promptkit/internal/domain"
"go.maximumdirect.net/promptkit/internal/jsonvalue"
)
type resolvedProfileSelection struct {
@@ -107,12 +106,6 @@ func (r *Runner) InspectProfile(
}
target, _ := resolveExecutionTarget(selection.profile, nil)
target.APIKey = ""
params, err := jsonvalue.CopyMap(target.ExtraParams)
if err != nil {
return nil, &OperationError{Category: ErrProfileLoad, Cause: fmt.Errorf("profile extra parameters: %w", err)}
}
target.ExtraParams = params
return &domain.ProfileInspection{
ProfileID: selection.id,
EffectiveModelParams: target,

View File

@@ -7,6 +7,7 @@ import (
"testing"
"go.maximumdirect.net/promptkit/internal/domain"
"go.maximumdirect.net/promptkit/internal/jsonvalue"
"go.maximumdirect.net/promptkit/internal/profile"
)
@@ -23,7 +24,16 @@ func (r *inspectionProfileRepository) GetProfile(_ context.Context, id string) (
if r.err != nil {
return nil, r.err
}
return r.profile, nil
if r.profile == nil {
return nil, nil
}
profile := *r.profile
if profile.ResolvedTarget != nil {
target := *profile.ResolvedTarget
target.ExtraParams = jsonvalue.CloneTrusted(target.ExtraParams).(map[string]any)
profile.ResolvedTarget = &target
}
return &profile, nil
}
func (r *inspectionProfileRepository) GetProfileIdentity(ctx context.Context, id string) (string, error) {

View File

@@ -58,6 +58,19 @@ func TestPreparationCompletesResolvedTargetThroughRequestOverrides(t *testing.T)
}
}
func TestResolvedTargetPreservesProviderMapSelection(t *testing.T) {
profile := &domain.ExecutionProfile{ResolvedTarget: &domain.ExecutionTarget{ExtraParams: map[string]any{"configured": true}}}
selected, _ := resolveExecutionTarget(profile, &domain.ExecutionTargetOverride{ExtraParams: map[string]any{}})
if selected.ExtraParams["configured"] != true {
t.Fatalf("empty override did not inherit provider settings: %#v", selected.ExtraParams)
}
profile.ResolvedTarget.ExtraParams = map[string]any{}
selected, _ = resolveExecutionTarget(profile, nil)
if selected.ExtraParams != nil {
t.Fatalf("empty provider settings changed projection: %#v", selected.ExtraParams)
}
}
func TestResolvedTargetCredentialAvailability(t *testing.T) {
profile := &domain.ExecutionProfile{ID: "direct", ResolvedTarget: &domain.ExecutionTarget{
Endpoint: "https://provider.example/v1", Model: "model", APIKeyRequired: true,

View File

@@ -592,14 +592,16 @@ func mergeExecutionTargetOverride(base domain.ExecutionTarget, presence domain.E
out.APIKeyEnv = override.APIKeyEnv
}
if len(override.ExtraParams) > 0 {
out.ExtraParams = copyExtraParams(override.ExtraParams)
out.ExtraParams = override.ExtraParams
}
return out, presence
}
func resolveExecutionTarget(profileValue *domain.ExecutionProfile, override *domain.ExecutionTargetOverride) (domain.ExecutionTarget, domain.ExecutionTargetPresence) {
out := *profileValue.ResolvedTarget
out.ExtraParams = copyExtraParams(out.ExtraParams)
if len(out.ExtraParams) == 0 {
out.ExtraParams = nil
}
presence := profileValue.TargetPresence
if override != nil {
return mergeExecutionTargetOverride(out, presence, *override)
@@ -624,17 +626,6 @@ func validateAPIKey(apiKeyEnv string, apiKey string, apiKeyRequired bool) error
return nil
}
func copyExtraParams(src map[string]any) map[string]any {
if len(src) == 0 {
return nil
}
cp := make(map[string]any, len(src))
for k, v := range src {
cp[k] = v
}
return cp
}
func resolveOutputContract(def *domain.PromptDefinition, override *domain.OutputContract) (domain.OutputContract, error) {
contract := def.Validation
if override != nil {

View File

@@ -112,7 +112,9 @@ func (r *Runner) resolveSmokeTestTarget(ctx context.Context, req domain.SmokeTes
settings.BackendID = selection.backend.ID
settings.Endpoint = selection.backend.Endpoint
settings.APIKeyEnv = selection.backend.APIKeyEnv
settings.ExtraParams = copyExtraParams(selection.backend.ExtraParams)
if len(selection.backend.ExtraParams) > 0 {
settings.ExtraParams = selection.backend.ExtraParams
}
presence := domain.ExecutionTargetPresence{}
if req.Execution != nil {
settings, presence = mergeExecutionTargetOverride(settings, presence, *req.Execution)