From b7ff37118c1ee4281ed2da0d3a139267826faf8c Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Fri, 9 Oct 2026 00:35:30 +0000 Subject: [PATCH] Add lightweight configuration lookups --- docs/internal/sources.md | 15 +++- internal/configuration/benchmark_test.go | 41 +++++++++-- internal/configuration/prompts.go | 57 +++++++++++---- internal/configuration/prompts_test.go | 90 ++++++++++++++++++++++++ internal/configuration/targets.go | 29 ++++++-- internal/configuration/targets_test.go | 14 ++++ 6 files changed, 221 insertions(+), 25 deletions(-) diff --git a/docs/internal/sources.md b/docs/internal/sources.md index 56e32ae..5c71896 100644 --- a/docs/internal/sources.md +++ b/docs/internal/sources.md @@ -57,6 +57,15 @@ captured presence state. Runtime rendering still checks request variables and input helpers. The [prompt adapter tests](../../internal/configuration/prompts_test.go) cover resource origins, context containment, capture, and selection. +The configuration adapter shares exact ID/version selection across its +internal prompt lookups. The execution snapshot lookup returns an owned prompt +definition and cached hash; metadata inspection returns owned input metadata +without copying execution templates. Profile selection likewise has an +identity-only lookup for consumers that do not need the execution target, +while the full profile lookup continues to return an owned target and deep copy +of provider extras. These lookups use captured indexes and do not query +ConfigKit again. + The `internal/prompt` requirement walker uses the captured parse trees and declaration metadata without executing templates or reading artifacts. It collects literal `input` names, direct root caller keys, and literal-key @@ -103,8 +112,10 @@ snapshots with backend defaults and presence/suppression state. A profile can remain partial until runtime overrides complete it. `InspectProfile` selects that captured target without prompt, artifact, schema, credential lookup, or provider work. Preparation applies runtime overrides and then checks target -completeness. The [target tests](../../internal/configuration/targets_test.go) -cover effective target interpretation, while the [catalog tests](../../internal/catalog/catalog_test.go) +completeness. Identity-only profile selection can identify a partial captured +profile without copying its target or requiring readiness. The +[target tests](../../internal/configuration/targets_test.go) cover effective +target interpretation, while the [catalog tests](../../internal/catalog/catalog_test.go) cover selected released assets. ## Ordinary Artifacts diff --git a/internal/configuration/benchmark_test.go b/internal/configuration/benchmark_test.go index d0c9e6c..370a907 100644 --- a/internal/configuration/benchmark_test.go +++ b/internal/configuration/benchmark_test.go @@ -13,10 +13,12 @@ import ( const benchmarkDefinitionCount = 128 var ( - constructionResult *loaded - selectedPrompt *domain.PromptDefinition - selectedPromptHash string - selectedProfile *domain.ExecutionProfile + constructionResult *loaded + selectedPrompt *domain.PromptDefinition + selectedPromptHash string + selectedPromptInspection *domain.PromptInspection + selectedProfile *domain.ExecutionProfile + selectedProfileIdentity string ) type configurationShape struct { @@ -234,6 +236,15 @@ func BenchmarkInspectionSelection(b *testing.B) { len(profile.ResolvedTarget.ExtraParams["provider_options"].(map[string]any)) != scenario.entries { b.Fatalf("profile lookup fixture is invalid: profile=%+v err=%v", profile, err) } + inspection, err := result.GetPromptInspection(ctx, "inspection", "1") + if err != nil || inspection.PromptID != "inspection" || inspection.PromptVersion != "1" || + len(inspection.Inputs) != 1 || inspection.Inputs[0].Name != "transcript" { + b.Fatalf("prompt inspection fixture is invalid: inspection=%+v err=%v", inspection, err) + } + identity, err := result.GetProfileIdentity(ctx, "small") + if err != nil || identity != "small" { + b.Fatalf("profile identity fixture is invalid: identity=%q err=%v", identity, err) + } b.Run("prompt/"+scenario.name, func(b *testing.B) { b.ReportAllocs() @@ -247,6 +258,17 @@ func BenchmarkInspectionSelection(b *testing.B) { } b.ReportMetric(float64(scenario.entries), "extra-entries/op") }) + b.Run("prompt_inspection/"+scenario.name, func(b *testing.B) { + b.ReportAllocs() + for b.Loop() { + inspection, err := result.GetPromptInspection(ctx, "inspection", "1") + if err != nil { + b.Fatal(err) + } + selectedPromptInspection = inspection + } + b.ReportMetric(float64(scenario.entries), "extra-entries/op") + }) b.Run("profile/"+scenario.name, func(b *testing.B) { b.ReportAllocs() for b.Loop() { @@ -258,5 +280,16 @@ func BenchmarkInspectionSelection(b *testing.B) { } b.ReportMetric(float64(scenario.entries), "extra-entries/op") }) + b.Run("profile_identity/"+scenario.name, func(b *testing.B) { + b.ReportAllocs() + for b.Loop() { + identity, err := result.GetProfileIdentity(ctx, "small") + if err != nil { + b.Fatal(err) + } + selectedProfileIdentity = identity + } + b.ReportMetric(float64(scenario.entries), "extra-entries/op") + }) } } diff --git a/internal/configuration/prompts.go b/internal/configuration/prompts.go index f783d46..2565e78 100644 --- a/internal/configuration/prompts.go +++ b/internal/configuration/prompts.go @@ -297,14 +297,14 @@ func (state *loaded) readContent(fieldPath configkit.Path, name string, lookupOr return string(content), nil } -func (state *loaded) prompt(id, version string) (*domain.PromptDefinition, domain.PromptInspection, error) { +func (state *loaded) lookupPromptEntry(id, version string) (*promptEntry, error) { if state == nil || strings.TrimSpace(id) == "" || (version != "" && strings.TrimSpace(version) == "") { - return nil, domain.PromptInspection{}, errPromptNotFound + return nil, errPromptNotFound } versions := state.prompts[id] if version == "" { if state.ambiguous[id] { - return nil, domain.PromptInspection{}, errPromptAmbiguous + return nil, errPromptAmbiguous } for selected := range versions { version = selected @@ -312,9 +312,12 @@ func (state *loaded) prompt(id, version string) (*domain.PromptDefinition, domai } entry := versions[version] if entry == nil { - return nil, domain.PromptInspection{}, errPromptNotFound + return nil, errPromptNotFound } - definition := entry.definition + return entry, nil +} + +func ownPromptDefinition(definition domain.PromptDefinition) *domain.PromptDefinition { definition.Inputs = append([]domain.PromptInput(nil), definition.Inputs...) definition.Templates = append([]domain.PromptMessageTemplate(nil), definition.Templates...) for index := range definition.Templates { @@ -323,9 +326,27 @@ func (state *loaded) prompt(id, version string) (*domain.PromptDefinition, domai definition.Templates[index].CacheControl = © } } - inspection := entry.inspection + return &definition +} + +func ownPromptInspection(inspection domain.PromptInspection) *domain.PromptInspection { inspection.Inputs = append([]domain.PromptInput(nil), inspection.Inputs...) - return &definition, inspection, nil + return &inspection +} + +func promptLookupError(err error) error { + if errors.Is(err, errPromptNotFound) { + return promptdef.ErrPromptDefinitionNotFound + } + return err +} + +func (state *loaded) prompt(id, version string) (*domain.PromptDefinition, domain.PromptInspection, error) { + entry, err := state.lookupPromptEntry(id, version) + if err != nil { + return nil, domain.PromptInspection{}, err + } + return ownPromptDefinition(entry.definition), *ownPromptInspection(entry.inspection), nil } // GetPromptSnapshot returns an independently owned captured definition and its @@ -334,14 +355,24 @@ func (state *loaded) GetPromptSnapshot(ctx context.Context, id, version string) if err := ctx.Err(); err != nil { return nil, "", err } - definition, inspection, err := state.prompt(id, version) - if errors.Is(err, errPromptNotFound) { - return nil, "", promptdef.ErrPromptDefinitionNotFound - } + entry, err := state.lookupPromptEntry(id, version) if err != nil { - return nil, "", err + return nil, "", promptLookupError(err) } - return definition, inspection.PromptHash, nil + return ownPromptDefinition(entry.definition), entry.hash, nil +} + +// GetPromptInspection returns an independently owned inspection of one +// captured prompt without copying its execution templates. +func (state *loaded) GetPromptInspection(ctx context.Context, id, version string) (*domain.PromptInspection, error) { + if err := ctx.Err(); err != nil { + return nil, err + } + entry, err := state.lookupPromptEntry(id, version) + if err != nil { + return nil, promptLookupError(err) + } + return ownPromptInspection(entry.inspection), nil } // GetPromptDefinition implements the runner's prompt lookup boundary. diff --git a/internal/configuration/prompts_test.go b/internal/configuration/prompts_test.go index 2afced8..c3d00d2 100644 --- a/internal/configuration/prompts_test.go +++ b/internal/configuration/prompts_test.go @@ -1,6 +1,7 @@ package configuration import ( + "context" "errors" "io/fs" "os" @@ -10,6 +11,7 @@ import ( "testing/fstest" "gitea.maximumdirect.net/eric/ConfigKit" + "gitea.maximumdirect.net/eric/promptkit/internal/promptdef" ) func TestLoadCapturesInheritedImportedContent(t *testing.T) { @@ -134,6 +136,94 @@ func TestLoadRejectsMalformedStaticSyntaxAndAmbiguousSelection(t *testing.T) { } } +func TestPromptInspectionLookupMatchesSnapshotSelectionAndOwnsInputs(t *testing.T) { + makePrompt := func(content string) map[string]any { + return map[string]any{ + "default_profile": "partial", + "inputs": []any{map[string]any{ + "name": "document", "required": true, + "content_type": " text/plain ", "description": " source document ", + }}, + "messages": []any{map[string]any{"role": "user", "content": content}}, + "output": map[string]any{"format": "text", "validation_mode": "none"}, + } + } + state, err := load(mapping("prompt inspection lookup", map[string]any{ + "profiles": map[string]any{"partial": map[string]any{}}, + "prompts": map[string]any{ + "multi": map[string]any{"v1": makePrompt("first"), "v2": makePrompt("second")}, + "single": map[string]any{"v1": makePrompt("only")}, + }, + }), nil) + if err != nil { + t.Fatal(err) + } + + for _, selection := range []struct { + id, version string + }{ + {id: "multi", version: "v2"}, + {id: "single"}, + } { + inspection, err := state.GetPromptInspection(context.Background(), selection.id, selection.version) + if err != nil { + t.Fatalf("inspect %q/%q: %v", selection.id, selection.version, err) + } + definition, hash, err := state.GetPromptSnapshot(context.Background(), selection.id, selection.version) + if err != nil { + t.Fatalf("snapshot %q/%q: %v", selection.id, selection.version, err) + } + if inspection.PromptID != definition.ID || inspection.PromptVersion != definition.Version || + inspection.PromptHash != hash || inspection.DefaultProfileID != "partial" || + len(inspection.Inputs) != 1 || inspection.Inputs[0].Name != "document" || + inspection.Inputs[0].ContentType != "text/plain" || inspection.Inputs[0].Description != "source document" { + t.Fatalf("inspection did not match the selected snapshot: inspection=%+v definition=%+v hash=%q", inspection, definition, hash) + } + if len(definition.Inputs) != len(inspection.Inputs) || definition.Inputs[0].Name != inspection.Inputs[0].Name { + t.Fatalf("definition and inspection inputs diverged: definition=%+v inspection=%+v", definition.Inputs, inspection.Inputs) + } + } + + owned, err := state.GetPromptInspection(context.Background(), "single", "") + if err != nil { + t.Fatal(err) + } + owned.Inputs[0].Name = "caller mutation" + owned.Inputs[0].Description = "caller mutation" + again, err := state.GetPromptInspection(context.Background(), "single", "v1") + if err != nil || again.Inputs[0].Name != "document" || again.Inputs[0].Description != "source document" { + t.Fatalf("inspection mutation escaped into captured state: inspection=%+v err=%v", again, err) + } + + for _, selection := range []struct { + id, version string + }{ + {id: "missing", version: "v1"}, + {id: "multi", version: "V2"}, + {id: " ", version: "v1"}, + } { + inspection, err := state.GetPromptInspection(context.Background(), selection.id, selection.version) + if inspection != nil || !errors.Is(err, promptdef.ErrPromptDefinitionNotFound) { + t.Errorf("inspection selection %q/%q=(%+v, %v), want not found", selection.id, selection.version, inspection, err) + } + definition, _, err := state.GetPromptSnapshot(context.Background(), selection.id, selection.version) + if definition != nil || !errors.Is(err, promptdef.ErrPromptDefinitionNotFound) { + t.Errorf("snapshot selection %q/%q=(%+v, %v), want not found", selection.id, selection.version, definition, err) + } + } + if _, err := state.GetPromptInspection(context.Background(), "multi", ""); !errors.Is(err, errPromptAmbiguous) { + t.Errorf("ambiguous inspection selection error=%v", err) + } + if _, _, err := state.GetPromptSnapshot(context.Background(), "multi", ""); !errors.Is(err, errPromptAmbiguous) { + t.Errorf("ambiguous snapshot selection error=%v", err) + } + ctx, cancel := context.WithCancel(context.Background()) + cancel() + if _, err := state.GetPromptInspection(ctx, "single", "v1"); !errors.Is(err, context.Canceled) { + t.Errorf("canceled inspection selection error=%v", err) + } +} + func TestLoadAcceptsEmptyInlineContentAndRejectsInvalidPromptFields(t *testing.T) { state, err := load(mapping("empty-content", map[string]any{"prompts": map[string]any{" exact.id ": map[string]any{"v1": map[string]any{ "inputs": []any{map[string]any{"name": " note ", "required": true}}, diff --git a/internal/configuration/targets.go b/internal/configuration/targets.go index 7d11943..bc8acd6 100644 --- a/internal/configuration/targets.go +++ b/internal/configuration/targets.go @@ -147,18 +147,26 @@ func overlayProviderMap(lower, upper map[string]any) (map[string]any, error) { return merged, nil } -// GetProfile returns an independently owned indexed profile for the internal -// runner's lookup boundary. -func (state *loaded) GetProfile(ctx context.Context, id string) (*domain.ExecutionProfile, error) { +func (state *loaded) lookupProfile(ctx context.Context, id string) (domain.ExecutionProfile, error) { if err := ctx.Err(); err != nil { - return nil, err + return domain.ExecutionProfile{}, err } if state == nil { - return nil, fmt.Errorf("%w: %q", profilepkg.ErrProfileNotFound, id) + return domain.ExecutionProfile{}, fmt.Errorf("%w: %q", profilepkg.ErrProfileNotFound, id) } profile, found := state.indexedProfiles[id] if !found { - return nil, fmt.Errorf("%w: %q", profilepkg.ErrProfileNotFound, id) + return domain.ExecutionProfile{}, fmt.Errorf("%w: %q", profilepkg.ErrProfileNotFound, id) + } + return profile, nil +} + +// GetProfile returns an independently owned indexed profile for the internal +// runner's lookup boundary. +func (state *loaded) GetProfile(ctx context.Context, id string) (*domain.ExecutionProfile, error) { + profile, err := state.lookupProfile(ctx, id) + if err != nil { + return nil, err } target := *profile.ResolvedTarget params, err := jsonvalue.CopyMap(target.ExtraParams) @@ -170,6 +178,15 @@ func (state *loaded) GetProfile(ctx context.Context, id string) (*domain.Executi return &profile, nil } +// GetProfileIdentity returns the exact lookup ID for a captured profile +// without copying its execution target. +func (state *loaded) GetProfileIdentity(ctx context.Context, id string) (string, error) { + if _, err := state.lookupProfile(ctx, id); err != nil { + return "", err + } + return id, nil +} + // GetBackend returns an independently owned effective backend definition. func (state *loaded) GetBackend(id string) (domain.Backend, error) { if state == nil { diff --git a/internal/configuration/targets_test.go b/internal/configuration/targets_test.go index e75111c..75727fd 100644 --- a/internal/configuration/targets_test.go +++ b/internal/configuration/targets_test.go @@ -3,6 +3,7 @@ package configuration import ( "context" "encoding/json" + "errors" "net/http" "net/http/httptest" "reflect" @@ -11,6 +12,7 @@ import ( "gitea.maximumdirect.net/eric/promptkit/internal/defaults" "gitea.maximumdirect.net/eric/promptkit/internal/domain" "gitea.maximumdirect.net/eric/promptkit/internal/llm" + profilepkg "gitea.maximumdirect.net/eric/promptkit/internal/profile" ) func TestLoadBuildsEffectiveTargetsAfterInheritance(t *testing.T) { @@ -89,6 +91,18 @@ func TestLoadBuildsEffectiveTargetsAfterInheritance(t *testing.T) { if partial.ResolvedTarget.Endpoint != "" || partial.ResolvedTarget.Model != "" { t.Fatalf("partial profile gained a runnable target: %+v", partial.ResolvedTarget) } + identity, err := state.GetProfileIdentity(context.Background(), "partial") + if err != nil || identity != "partial" { + t.Fatalf("partial profile identity=(%q, %v)", identity, err) + } + if _, err := state.GetProfileIdentity(context.Background(), "missing"); !errors.Is(err, profilepkg.ErrProfileNotFound) { + t.Fatalf("missing profile identity error=%v", err) + } + ctx, cancel := context.WithCancel(context.Background()) + cancel() + if _, err := state.GetProfileIdentity(ctx, "partial"); !errors.Is(err, context.Canceled) { + t.Fatalf("canceled profile identity lookup error=%v", err) + } endpointOnly, _ := state.GetProfile(context.Background(), "endpoint-only") if endpointOnly.ResolvedTarget.Endpoint != "https://standalone.example/v1" || endpointOnly.ResolvedTarget.BackendID != "" || endpointOnly.ResolvedTarget.Model != "" {