Add lightweight configuration lookups
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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}},
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 != "" {
|
||||
|
||||
Reference in New Issue
Block a user