Store one prompt definition per ID

This commit is contained in:
2026-10-17 05:41:21 +00:00
parent 0cd833513c
commit d40a010538
28 changed files with 393 additions and 445 deletions

View File

@@ -52,7 +52,16 @@ func contractPrompt(defaultProfile string, content string, inputs []any, session
}
func oneVersionPrompt(id, version string, definition map[string]any) map[string]any {
return map[string]any{id: map[string]any{version: definition}}
return map[string]any{id: promptDefinitionWithVersion(version, definition)}
}
func promptDefinitionWithVersion(version string, definition map[string]any) map[string]any {
result := make(map[string]any, len(definition)+1)
result["version"] = version
for key, value := range definition {
result[key] = value
}
return result
}
var noValidationOutput = map[string]any{"format": "text", "validation_mode": "none"}
@@ -123,16 +132,12 @@ func TestInspectRequirementsEnumeratesCapturedDependenciesAndInactiveNames(t *te
}
}
func TestInspectRequirementsSelectionUsesExactVersionsAndProfileIdentity(t *testing.T) {
func TestInspectRequirementsUsesPromptIDsAndProfileIdentity(t *testing.T) {
prompts := map[string]any{
"multi": map[string]any{
"v1": contractPrompt("first", `{{input "one"}}`, nil, "", noValidationOutput),
"v2": contractPrompt("second", `{{input "two"}}`, nil, "", noValidationOutput),
},
"without-default": map[string]any{
"v1": contractPrompt("", "plain", nil, "", noValidationOutput),
},
"direct-required": map[string]any{"v1": contractPrompt("direct", "plain", nil, "", noValidationOutput)},
"first-prompt": promptDefinitionWithVersion("v1", contractPrompt("first", `{{input "one"}}`, nil, "", noValidationOutput)),
"second-prompt": promptDefinitionWithVersion("v2", contractPrompt("second", `{{input "two"}}`, nil, "", noValidationOutput)),
"without-default": contractPrompt("", "plain", nil, "", noValidationOutput),
"direct-required": promptDefinitionWithVersion("v1", contractPrompt("direct", "plain", nil, "", noValidationOutput)),
}
profiles := map[string]any{
"first": map[string]any{"model": "first-model"},
@@ -140,26 +145,20 @@ func TestInspectRequirementsSelectionUsesExactVersionsAndProfileIdentity(t *test
"direct": map[string]any{"endpoint": "https://example.test/v1", "model": "direct-model", "api_key_required": true},
}
engine := requirementsEngine(t, prompts, profiles)
if _, err := engine.InspectRequirements(context.Background(), promptkit.RequirementInspectionRequest{PromptID: "multi"}); !errors.Is(err, promptkit.ErrPromptLoad) {
t.Fatalf("ambiguous omitted version error=%v", err)
}
first, err := engine.InspectRequirements(context.Background(), promptkit.RequirementInspectionRequest{PromptID: "multi", PromptVersion: "v1"})
first, err := engine.InspectRequirements(context.Background(), promptkit.RequirementInspectionRequest{PromptID: "first-prompt"})
if err != nil || first.PromptVersion != "v1" || first.ProfileID != "first" || len(first.Inputs) != 1 || first.Inputs[0].Name != "one" {
t.Fatalf("exact first version/default profile=(%+v, %v)", first, err)
t.Fatalf("first prompt ID/default profile=(%+v, %v)", first, err)
}
explicit, err := engine.InspectRequirements(context.Background(), promptkit.RequirementInspectionRequest{
PromptID: "multi", PromptVersion: "v2", ProfileID: "first",
second, err := engine.InspectRequirements(context.Background(), promptkit.RequirementInspectionRequest{
PromptID: "second-prompt", ProfileID: "first",
})
if err != nil || explicit.PromptVersion != "v2" || explicit.ProfileID != "first" || explicit.Inputs[0].Name != "two" {
t.Fatalf("exact version/request profile=(%+v, %v)", explicit, err)
if err != nil || second.PromptVersion != "v2" || second.ProfileID != "first" || second.Inputs[0].Name != "two" {
t.Fatalf("second prompt ID/request profile=(%+v, %v)", second, err)
}
if _, err := engine.InspectRequirements(context.Background(), promptkit.RequirementInspectionRequest{PromptID: "Multi", PromptVersion: "v1"}); !errors.Is(err, promptkit.ErrPromptNotFound) {
if _, err := engine.InspectRequirements(context.Background(), promptkit.RequirementInspectionRequest{PromptID: "First-Prompt"}); !errors.Is(err, promptkit.ErrPromptNotFound) {
t.Fatalf("case-folded prompt ID unexpectedly selected: %v", err)
}
if _, err := engine.InspectRequirements(context.Background(), promptkit.RequirementInspectionRequest{PromptID: "multi", PromptVersion: "V1"}); !errors.Is(err, promptkit.ErrPromptNotFound) {
t.Fatalf("case-folded version unexpectedly selected: %v", err)
}
if _, err := engine.InspectRequirements(context.Background(), promptkit.RequirementInspectionRequest{PromptID: "multi", PromptVersion: "v1", ProfileID: "missing"}); !errors.Is(err, promptkit.ErrProfileNotFound) {
if _, err := engine.InspectRequirements(context.Background(), promptkit.RequirementInspectionRequest{PromptID: "first-prompt", ProfileID: "missing"}); !errors.Is(err, promptkit.ErrProfileNotFound) {
t.Fatalf("missing profile error=%v", err)
}
if _, err := engine.InspectRequirements(context.Background(), promptkit.RequirementInspectionRequest{PromptID: "without-default"}); !errors.Is(err, promptkit.ErrProfileRequired) || !errors.Is(err, promptkit.ErrInvalidRequest) {
@@ -173,7 +172,7 @@ func TestInspectRequirementsSelectionUsesExactVersionsAndProfileIdentity(t *test
}
ctx, cancel := context.WithCancel(context.Background())
cancel()
if _, err := engine.InspectRequirements(ctx, promptkit.RequirementInspectionRequest{PromptID: "multi", PromptVersion: "v1"}); !errors.Is(err, context.Canceled) {
if _, err := engine.InspectRequirements(ctx, promptkit.RequirementInspectionRequest{PromptID: "first-prompt"}); !errors.Is(err, context.Canceled) {
t.Fatalf("canceled inspection error=%v", err)
}
}
@@ -202,11 +201,11 @@ func TestInspectPromptHashMatchesPreparationForCapturedConfiguration(t *testing.
func TestInspectRequirementsReportsConditionalAndCompleteOptionalInventories(t *testing.T) {
prompts := map[string]any{
"conditional": map[string]any{"v1": contractPrompt("profile",
`{{if .mode}}{{input "left"}}{{else}}{{input "right"}}{{end}}`, nil, "", noValidationOutput)},
"optional": map[string]any{"v1": contractPrompt("profile", `{{index . "lookup"}}`,
[]any{map[string]any{"name": "declared-optional"}}, "", noValidationOutput)},
"empty": map[string]any{"v1": contractPrompt("profile", "plain", nil, "", noValidationOutput)},
"conditional": promptDefinitionWithVersion("v1", contractPrompt("profile",
`{{if .mode}}{{input "left"}}{{else}}{{input "right"}}{{end}}`, nil, "", noValidationOutput)),
"optional": promptDefinitionWithVersion("v1", contractPrompt("profile", `{{index . "lookup"}}`,
[]any{map[string]any{"name": "declared-optional"}}, "", noValidationOutput)),
"empty": promptDefinitionWithVersion("v1", contractPrompt("profile", "plain", nil, "", noValidationOutput)),
}
engine := requirementsEngine(t, prompts, map[string]any{"profile": map[string]any{"model": "partial"}})
conditional, err := engine.InspectRequirements(context.Background(), promptkit.RequirementInspectionRequest{PromptID: "conditional"})