package promptkit_test import ( "bytes" "context" "encoding/json" "errors" "strings" "testing" "go.maximumdirect.net/configkit" "go.maximumdirect.net/promptkit" ) func TestProgrammaticSourcesPreserveOrderAndRejectDuplicates(t *testing.T) { endpoint := "https://example.invalid/v1" params := map[string]any{"visible": "original"} backendSource := promptkit.BackendSource("backends", []promptkit.BackendConfig{ {ID: "zeta", Endpoint: &endpoint, ExtraParams: params}, {ID: "alpha", Endpoint: &endpoint}, }) profileSource := promptkit.ProfileSource("profiles", []promptkit.ProfileConfig{ {ID: "zeta", ExtraParams: params}, {ID: "alpha"}, }) params["visible"] = "changed" engine, err := promptkit.NewEngine(promptkit.Config{Sources: promptkit.ConfigurationSources{ Underlays: []configkit.Underlay{{Inputs: []configkit.Input{{Source: backendSource}, {Source: profileSource}}}}, }}, promptkit.WithBundledOpenRouter(false)) if err != nil { t.Fatal(err) } view, err := engine.InspectConfiguration() if err != nil { t.Fatal(err) } var report bytes.Buffer if err := view.WriteEffective(&report); err != nil { t.Fatal(err) } contents := report.String() if strings.Count(contents, "original") != 2 || strings.Contains(contents, "changed") { t.Fatalf("source ownership was lost: %s", contents) } for _, kind := range []string{"backends", "profiles"} { for index, id := range []string{"zeta", "alpha"} { entry, found := view.Explain(configkit.Keys(kind).Index(index).Key("id")) if !found || !strings.Contains(entry.Effective.YAML, id) { t.Fatalf("%s entry %d = %+v, want %s", kind, index, entry, id) } } } for _, source := range []configkit.Source{ promptkit.BackendSource("duplicate backends", []promptkit.BackendConfig{{ID: "duplicate", Endpoint: &endpoint}, {ID: "duplicate", Endpoint: &endpoint}}), promptkit.ProfileSource("duplicate profiles", []promptkit.ProfileConfig{{ID: "duplicate"}, {ID: "duplicate"}}), } { _, err := promptkit.NewEngine(promptkit.Config{Sources: promptkit.ConfigurationSources{Main: &configkit.Input{Source: source}}}) if !errors.Is(err, promptkit.ErrInvalidConfig) { t.Fatalf("duplicate source error = %v, want ErrInvalidConfig", err) } } } func TestProgrammaticProfileVariantInherits(t *testing.T) { parent, endpoint, model, timeout := "base", "https://example.invalid/v1", "synthetic-model", 15 source := promptkit.ProfileSource("profiles", []promptkit.ProfileConfig{ {ID: parent, Endpoint: &endpoint, Model: &model}, {ID: "child", Extends: &parent, TimeoutSeconds: &timeout}, }) engine, err := promptkit.NewEngine(promptkit.Config{Sources: promptkit.ConfigurationSources{Main: &configkit.Input{Source: source}}}) if err != nil { t.Fatal(err) } profile, err := engine.InspectProfile(context.Background(), "child") if err != nil || profile.EffectiveModelParams.Model != model || profile.EffectiveModelParams.Endpoint != endpoint || profile.EffectiveModelParams.TimeoutSeconds != timeout { t.Fatalf("inherited profile = %+v, %v", profile, err) } } func TestProgrammaticSourcesCaptureNestedValuesAndDeferInvalidValues(t *testing.T) { endpoint := "https://example.invalid/v1" type namedString string cyclic := map[string]any{} cyclic["self"] = cyclic for _, kind := range []string{"backend", "profile"} { makeSource := func(params map[string]any) configkit.Source { if kind == "backend" { return promptkit.BackendSource("backend", []promptkit.BackendConfig{{ID: "local", Endpoint: &endpoint, ExtraParams: params}}) } return promptkit.ProfileSource("profile", []promptkit.ProfileConfig{{ID: "local", ExtraParams: params}}) } load := func(source configkit.Source) (*promptkit.Engine, error) { return promptkit.NewEngine(promptkit.Config{Sources: promptkit.ConfigurationSources{Main: &configkit.Input{Source: source}}}, promptkit.WithBundledOpenRouter(false)) } t.Run(kind+"/capture", func(t *testing.T) { values := map[string]any{"nested": map[string]any{"items": []any{"original", int64(42), true, nil}}} source := makeSource(values) values["nested"].(map[string]any)["items"].([]any)[0] = "mutated" engine, err := load(source) if err != nil { t.Fatal(err) } view, err := engine.InspectConfiguration() if err != nil { t.Fatal(err) } var output bytes.Buffer if err := view.WriteEffective(&output); err != nil { t.Fatal(err) } if !strings.Contains(output.String(), "original") || strings.Contains(output.String(), "mutated") { t.Fatalf("captured configuration = %s", output.String()) } }) for name, value := range map[string]any{"number": json.Number("1.25"), "typed slice": []string{"value"}, "named scalar": namedString("value"), "pointer": &endpoint, "cycle": cyclic} { t.Run(kind+"/"+name, func(t *testing.T) { source := makeSource(map[string]any{"value": value}) _, err := load(source) var loadErr *configkit.LoadError if !errors.As(err, &loadErr) || len(loadErr.Diagnostics()) == 0 { t.Fatalf("source error = %v", err) } }) } } }