Update public configuration and inventory contracts

This commit is contained in:
2026-11-02 12:50:58 +00:00
parent 682cb84c82
commit 6b8eefd18b
7 changed files with 89 additions and 98 deletions

View File

@@ -17,8 +17,8 @@ import (
func TestListIdentitiesBasicContract(t *testing.T) {
engine, err := promptkit.NewEngine(promptkit.Config{Sources: promptkit.ConfigurationSources{Main: &configkit.Input{
Source: configkit.Mapping("listing", map[string]any{
"profiles": map[string]any{"configured-profile": map[string]any{"model": "example-model"}},
"prompts": map[string]any{"example-prompt": promptDefinitionWithVersion("10", listingContractPrompt())},
"profiles": []any{map[string]any{"id": "configured-profile", "model": "example-model"}},
"prompts": []any{listingContractPrompt("example-prompt")},
}),
}}})
if err != nil {
@@ -38,13 +38,13 @@ func TestListIdentitiesBasicContract(t *testing.T) {
t.Fatal(err)
}
want := []promptkit.PromptIdentity{
{ID: "example-prompt", Version: stringPointerForTest("10")},
{ID: "example-prompt"},
}
if len(prompts) != len(want) {
t.Fatalf("prompt listing = %#v, want %#v", prompts, want)
}
for i := range want {
if prompts[i].ID != want[i].ID || prompts[i].Version == nil || *prompts[i].Version != *want[i].Version {
if prompts[i].ID != want[i].ID {
t.Fatalf("prompt listing = %#v, want %#v", prompts, want)
}
}
@@ -54,8 +54,7 @@ func TestListIdentitiesBasicContract(t *testing.T) {
t.Fatalf("listed profile could not be inspected: (%+v, %v)", profile, err)
}
prompt, err := engine.InspectPrompt(context.Background(), prompts[0].ID)
if err != nil || prompt == nil || prompt.PromptID != prompts[0].ID || prompt.PromptVersion == nil ||
*prompt.PromptVersion != *prompts[0].Version {
if err != nil || prompt == nil || prompt.PromptID != prompts[0].ID {
t.Fatalf("listed prompt could not be inspected: (%+v, %v)", prompt, err)
}
}
@@ -135,16 +134,15 @@ func TestScopedIdentityListingsApplyNamespaceFilters(t *testing.T) {
}
prompts, err := scoped.ListPrompts(context.Background(), promptkit.NamespaceFilter{Mode: promptkit.NamespaceNamed, Name: "team"})
if err != nil || len(prompts) != 1 || prompts[0].ID != "team/prompt" || prompts[0].Version == nil || *prompts[0].Version != "team-v1" {
if err != nil || len(prompts) != 1 || prompts[0].ID != "team/prompt" {
t.Fatalf("named prompt identity = %#v, %v", prompts, err)
}
if _, err := scoped.InspectPrompt(context.Background(), prompts[0].ID); err != nil {
t.Fatalf("listed full prompt ID did not round trip: %v", err)
}
*prompts[0].Version = "caller change"
prompts[0].ID = "caller change"
prompts, err = scoped.ListPrompts(context.Background(), promptkit.NamespaceFilter{Mode: promptkit.NamespaceNamed, Name: "team"})
if err != nil || len(prompts) != 1 || prompts[0].ID != "team/prompt" || prompts[0].Version == nil || *prompts[0].Version != "team-v1" {
if err != nil || len(prompts) != 1 || prompts[0].ID != "team/prompt" {
t.Fatalf("mutating filtered prompt inventory escaped: %#v, %v", prompts, err)
}
profiles, err := scoped.ListProfiles(context.Background(), promptkit.NamespaceFilter{Mode: promptkit.NamespaceNamed, Name: "team"})
@@ -214,9 +212,9 @@ func newNamespaceListingEngine(t *testing.T) *promptkit.Engine {
t.Helper()
collection := func(namespace string) map[string]any {
return map[string]any{
"backends": map[string]any{"backend": map[string]any{"endpoint": "https://example.test/v1"}},
"profiles": map[string]any{"profile": map[string]any{"backend": namespace + "/backend", "model": "example-model"}},
"prompts": map[string]any{"prompt": promptDefinitionWithVersion("team-v1", listingContractPrompt())},
"backends": []any{map[string]any{"id": "backend", "endpoint": "https://example.test/v1"}},
"profiles": []any{map[string]any{"id": "profile", "backend": namespace + "/backend", "model": "example-model"}},
"prompts": []any{listingContractPrompt("prompt")},
}
}
input := configkit.Input{Source: configkit.Mapping("namespaced listing", map[string]any{
@@ -224,9 +222,9 @@ func newNamespaceListingEngine(t *testing.T) *promptkit.Engine {
"team": collection("team"),
"team-blue": collection("team-blue"),
},
"backends": map[string]any{"root-backend": map[string]any{"endpoint": "https://root.example.test/v1"}},
"profiles": map[string]any{"root-profile": map[string]any{"backend": "root-backend", "model": "root-model"}},
"prompts": map[string]any{"root-prompt": promptDefinitionWithVersion("root-v1", listingContractPrompt())},
"backends": []any{map[string]any{"id": "root-backend", "endpoint": "https://root.example.test/v1"}},
"profiles": []any{map[string]any{"id": "root-profile", "backend": "root-backend", "model": "root-model"}},
"prompts": []any{listingContractPrompt("root-prompt")},
})}
engine, err := promptkit.NewEngine(promptkit.Config{Sources: promptkit.ConfigurationSources{Main: &input}})
if err != nil {
@@ -241,18 +239,18 @@ func newNamespaceListingEngine(t *testing.T) *promptkit.Engine {
func TestResourceAndCollectionInventories(t *testing.T) {
underlay := configkit.Input{Source: configkit.Mapping("inventory defaults", map[string]any{
"backends": map[string]any{"root-backend": map[string]any{"endpoint": "https://root.example.test/v1"}},
"profiles": map[string]any{"root-profile": map[string]any{"endpoint": "https://root.example.test/v1", "model": "root-model"}},
"prompts": map[string]any{"root-prompt": listingContractPrompt()},
"backends": []any{map[string]any{"id": "root-backend", "endpoint": "https://root.example.test/v1"}},
"profiles": []any{map[string]any{"id": "root-profile", "endpoint": "https://root.example.test/v1", "model": "root-model"}},
"prompts": []any{listingContractPrompt("root-prompt")},
"collections": map[string]any{
"alpha": map[string]any{
"backends": map[string]any{"api": map[string]any{"endpoint": "https://alpha.example.test/v1"}},
"profiles": map[string]any{"profile": map[string]any{"backend": "alpha/api", "model": "alpha-model"}},
"prompts": map[string]any{"prompt": listingContractPrompt()},
"backends": []any{map[string]any{"id": "api", "endpoint": "https://alpha.example.test/v1"}},
"profiles": []any{map[string]any{"id": "profile", "backend": "alpha/api", "model": "alpha-model"}},
"prompts": []any{listingContractPrompt("prompt")},
},
"alpha-beta": map[string]any{"prompts": map[string]any{"prompt": listingContractPrompt()}},
"beta": map[string]any{"backends": map[string]any{"api": map[string]any{"endpoint": "https://beta.example.test/v1"}}},
"resource-only": map[string]any{"profiles": map[string]any{"profile": map[string]any{"endpoint": "https://resource.example.test/v1", "model": "resource-model"}}},
"alpha-beta": map[string]any{"prompts": []any{listingContractPrompt("prompt")}},
"beta": map[string]any{"backends": []any{map[string]any{"id": "api", "endpoint": "https://beta.example.test/v1"}}},
"resource-only": map[string]any{"profiles": []any{map[string]any{"id": "profile", "endpoint": "https://resource.example.test/v1", "model": "resource-model"}}},
"metadata-only": map[string]any{"release_version": "v1"},
"empty-label": map[string]any{"release_version": ""},
"null-label": map[string]any{"release_version": nil},
@@ -363,8 +361,8 @@ func TestListIdentitiesInvalidEngine(t *testing.T) {
func TestListIdentitiesPreserveContextErrorsWithoutPartialResults(t *testing.T) {
engine, err := promptkit.NewEngine(promptkit.Config{Sources: promptkit.ConfigurationSources{Main: &configkit.Input{
Source: configkit.Mapping("listing", map[string]any{
"profiles": map[string]any{"profile": map[string]any{}},
"prompts": map[string]any{"example": promptDefinitionWithVersion("v1", listingContractPrompt())},
"profiles": []any{map[string]any{"id": "profile"}},
"prompts": []any{listingContractPrompt("example")},
}),
}}})
if err != nil {
@@ -399,26 +397,20 @@ func TestListIdentitiesPreserveContextErrorsWithoutPartialResults(t *testing.T)
func TestListIdentitiesUseEffectiveLayeredMembership(t *testing.T) {
underlay := configkit.Input{Source: configkit.Mapping("consumer defaults", map[string]any{
"collections": map[string]any{"shared": map[string]any{
"profiles": map[string]any{
"base": map[string]any{"endpoint": "https://example.test/v1", "model": "base-model"},
"child": map[string]any{"extends": "base"},
"overlay": map[string]any{"endpoint": "https://example.test/v1", "model": "old-model"},
},
"prompts": map[string]any{
"prompt": promptDefinitionWithVersion("v1", listingContractPrompt()),
"profiles": []any{
map[string]any{"id": "base", "endpoint": "https://example.test/v1", "model": "base-model"},
map[string]any{"id": "child", "extends": map[string]any{"id": "base"}},
map[string]any{"id": "overlay", "endpoint": "https://example.test/v1", "model": "old-model"},
},
"prompts": []any{listingContractPrompt("prompt")},
}},
"prompts": map[string]any{
"underlay-only": promptDefinitionWithVersion("v1", listingContractPrompt()),
},
"prompts": []any{listingContractPrompt("underlay-only")},
})}
main := configkit.Input{Source: configkit.Mapping("application overlay", map[string]any{
"collections": map[string]any{"shared": map[string]any{"profiles": map[string]any{
"overlay": map[string]any{"model": "effective-model"},
"collections": map[string]any{"shared": map[string]any{"profiles": []any{
map[string]any{"id": "overlay", "model": "effective-model"},
}}},
"prompts": map[string]any{
"main-only": promptDefinitionWithVersion("v3", listingContractPrompt()),
},
"prompts": []any{listingContractPrompt("main-only")},
})}
engine, err := promptkit.NewEngine(promptkit.Config{Sources: promptkit.ConfigurationSources{
Underlays: []configkit.Underlay{{Inputs: []configkit.Input{underlay}}},
@@ -459,14 +451,14 @@ func TestListIdentitiesUseEffectiveLayeredMembership(t *testing.T) {
t.Fatal(err)
}
wantPrompts := []promptkit.PromptIdentity{
{ID: "main-only", Version: stringPointerForTest("v3")},
{ID: "shared/prompt", Version: stringPointerForTest("v1")},
{ID: "underlay-only", Version: stringPointerForTest("v1")},
{ID: "main-only"},
{ID: "shared/prompt"},
{ID: "underlay-only"},
}
if !reflect.DeepEqual(prompts, wantPrompts) {
t.Fatalf("effective prompt identities = %#v, want %#v", prompts, wantPrompts)
}
if got := countListingPrompt(prompts, "shared/prompt", "v1"); got != 1 {
if got := countListingPrompt(prompts, "shared/prompt"); got != 1 {
t.Fatalf("overlaid prompt identity appears %d times, want 1", got)
}
}
@@ -488,8 +480,8 @@ func TestListIdentitiesEmptyEffectiveConfiguration(t *testing.T) {
func TestListIdentitiesAreOwnedAndSafeForConcurrentUse(t *testing.T) {
engine, err := newListingContractEngine(t, map[string]any{
"profiles": map[string]any{"profile": map[string]any{"model": "partial-model"}},
"prompts": map[string]any{"prompt": promptDefinitionWithVersion("v1", listingContractPrompt())},
"profiles": []any{map[string]any{"id": "profile", "model": "partial-model"}},
"prompts": []any{listingContractPrompt("prompt")},
})
if err != nil {
t.Fatal(err)
@@ -511,9 +503,6 @@ func TestListIdentitiesAreOwnedAndSafeForConcurrentUse(t *testing.T) {
for i := range prompts {
if prompts[i].ID == "prompt" {
prompts[i].ID = "caller mutation"
if prompts[i].Version != nil {
*prompts[i].Version = "caller mutation"
}
}
}
profiles, err = engine.ListProfiles(context.Background())
@@ -521,7 +510,7 @@ func TestListIdentitiesAreOwnedAndSafeForConcurrentUse(t *testing.T) {
t.Fatalf("profile result mutation escaped into engine: %#v, %v", profiles, err)
}
prompts, err = engine.ListPrompts(context.Background())
if err != nil || countListingPrompt(prompts, "prompt", "v1") != 1 {
if err != nil || countListingPrompt(prompts, "prompt") != 1 {
t.Fatalf("prompt result mutation escaped into engine: %#v, %v", prompts, err)
}
@@ -557,9 +546,6 @@ func TestListIdentitiesAreOwnedAndSafeForConcurrentUse(t *testing.T) {
return
}
prompts[0].ID = "worker mutation"
if prompts[0].Version != nil {
*prompts[0].Version = "worker mutation"
}
if _, err := engine.InspectProfile(context.Background(), "profile"); err != nil {
results <- fmt.Errorf("inspect profile: %w", err)
@@ -582,7 +568,7 @@ func TestListIdentitiesAreOwnedAndSafeForConcurrentUse(t *testing.T) {
func TestListIdentitiesUseCapturedSourcesWithoutExecutionWork(t *testing.T) {
files := fstest.MapFS{
"config/listing.yaml": &fstest.MapFile{Data: []byte("profiles:\n captured-partial:\n model: partial-model\nprompts:\n captured-prompt:\n version: v1\n messages:\n - role: user\n content: Hello.\n output:\n format: text\n validation_mode: basic\n")},
"config/listing.yaml": &fstest.MapFile{Data: []byte("profiles:\n - id: captured-partial\n model: partial-model\nprompts:\n - id: captured-prompt\n messages:\n - role: user\n content: Hello.\n output:\n format: text\n validation_mode: basic\n")},
}
inputs, err := promptkit.FilesystemInputs("application listing", files, "config")
if err != nil {
@@ -594,20 +580,21 @@ func TestListIdentitiesUseCapturedSourcesWithoutExecutionWork(t *testing.T) {
if err != nil {
t.Fatal(err)
}
files["config/listing.yaml"].Data = []byte("profiles:\n replacement-profile: {}\nprompts:\n replacement-prompt:\n version: v2\n messages:\n - role: user\n content: Changed.\n output:\n format: text\n validation_mode: basic\n")
files["config/listing.yaml"].Data = []byte("profiles:\n - id: replacement-profile\nprompts:\n - id: replacement-prompt\n messages:\n - role: user\n content: Changed.\n output:\n format: text\n validation_mode: basic\n")
profiles, err := engine.ListProfiles(context.Background())
if err != nil || !containsListingProfile(profiles, "captured-partial") || containsListingProfile(profiles, "replacement-profile") {
t.Fatalf("profile listing did not use captured source: %#v, %v", profiles, err)
}
prompts, err := engine.ListPrompts(context.Background())
if err != nil || countListingPrompt(prompts, "captured-prompt", "v1") != 1 || countListingPrompt(prompts, "replacement-prompt", "v2") != 0 {
if err != nil || countListingPrompt(prompts, "captured-prompt") != 1 || countListingPrompt(prompts, "replacement-prompt") != 0 {
t.Fatalf("prompt listing did not use captured source: %#v, %v", prompts, err)
}
}
func listingContractPrompt() map[string]any {
func listingContractPrompt(id string) map[string]any {
return map[string]any{
"id": id,
"messages": []any{map[string]any{"role": "user", "content": "Hello."}},
"output": map[string]any{"format": "text", "validation_mode": "basic"},
}
@@ -632,10 +619,10 @@ func countListingProfile(profiles []string, id string) int {
return count
}
func countListingPrompt(prompts []promptkit.PromptIdentity, id, version string) int {
func countListingPrompt(prompts []promptkit.PromptIdentity, id string) int {
count := 0
for _, prompt := range prompts {
if prompt.ID == id && prompt.Version != nil && *prompt.Version == version {
if prompt.ID == id {
count++
}
}