package promptkit_test import ( "context" "errors" "sync" "testing" "gitea.maximumdirect.net/eric/ConfigKit" "gitea.maximumdirect.net/eric/promptkit" ) func TestWithNamespacesRoutesOrdinarySelectionsAndPreservesViews(t *testing.T) { client := &fakeLLMClient{response: &promptkit.GenerateResponse{Content: "reply"}} engine := newNamespacedContractEngine(t, client) alpha, err := engine.WithNamespaces(promptkit.Namespaces{Prompt: "alpha", Profile: "alpha"}) if err != nil { t.Fatal(err) } beta, err := engine.WithNamespaces(promptkit.Namespaces{Prompt: "beta", Profile: "beta"}) if err != nil { t.Fatal(err) } request := promptkit.RunRequest{PromptID: "shared", ProfileID: "shared"} prepared, err := alpha.Prepare(context.Background(), request) if err != nil { t.Fatalf("prepare scoped request: %v", err) } assertNamespacedSelection(t, prepared.PromptID, prepared.SelectedProfileID, prepared.SelectedBackendID, "alpha") betaPrepared, err := beta.Prepare(context.Background(), request) if err != nil { t.Fatalf("prepare independent view: %v", err) } assertNamespacedSelection(t, betaPrepared.PromptID, betaPrepared.SelectedProfileID, betaPrepared.SelectedBackendID, "beta") if err := alpha.ValidateRequest(context.Background(), request); err != nil { t.Fatalf("validate scoped request: %v", err) } qualified, err := alpha.Prepare(context.Background(), promptkit.RunRequest{PromptID: "beta/shared", ProfileID: "beta/shared"}) if err != nil { t.Fatalf("prepare qualified bypass: %v", err) } assertNamespacedSelection(t, qualified.PromptID, qualified.SelectedProfileID, qualified.SelectedBackendID, "beta") preparedExecution, err := alpha.PrepareExecution(context.Background(), request) if err != nil { t.Fatalf("prepare execution: %v", err) } details := preparedExecution.Details() assertNamespacedSelection(t, details.PromptID, details.SelectedProfileID, details.SelectedBackendID, "alpha") // A handle captures its qualified selection and remains runnable through the // original facade because the views share the same assembled runner. result, err := engine.RunPrepared(context.Background(), preparedExecution) if err != nil { t.Fatalf("run scoped prepared handle through original view: %v", err) } assertNamespacedSelection(t, result.PromptID, result.SelectedProfileID, result.SelectedBackendID, "alpha") var events []promptkit.ExecutionEvent runResult, err := alpha.Run(context.Background(), promptkit.RunRequest{ PromptID: "shared", ProfileID: "shared", Observer: func(event promptkit.ExecutionEvent) { events = append(events, event) }, }) if err != nil { t.Fatalf("run scoped request: %v", err) } assertNamespacedSelection(t, runResult.PromptID, runResult.SelectedProfileID, runResult.SelectedBackendID, "alpha") var sawScopedEvent bool for _, event := range events { if event.PromptID == "alpha/shared" && event.ProfileID == "alpha/shared" && event.BackendID == "alpha/backend" { sawScopedEvent = true } } if !sawScopedEvent { t.Fatalf("observer events did not retain qualified identities: %+v", events) } // The original engine remains unscoped and can still select the exact IDs. original, err := engine.Prepare(context.Background(), promptkit.RunRequest{PromptID: "root-only", ProfileID: "root-only"}) if err != nil { t.Fatalf("original engine was changed by scoped views: %v", err) } if original.PromptID != "root-only" || original.SelectedProfileID != "root-only" || original.EffectiveModelParams.Model != "root-model" { t.Fatalf("original engine selection = %+v, want unqualified root resources", original) } } func TestWithNamespacesHasNoFallbackAndValidatesAtTheCorrectBoundary(t *testing.T) { engine := newNamespacedContractEngine(t, &fakeLLMClient{response: &promptkit.GenerateResponse{Content: "reply"}}) scoped, err := engine.WithNamespaces(promptkit.Namespaces{Prompt: "alpha", Profile: "alpha"}) if err != nil { t.Fatal(err) } if _, err := scoped.Prepare(context.Background(), promptkit.RunRequest{PromptID: "root-only", ProfileID: "alpha/shared"}); !errors.Is(err, promptkit.ErrPromptNotFound) { t.Fatalf("root prompt fallback error = %v, want ErrPromptNotFound", err) } if _, err := scoped.Prepare(context.Background(), promptkit.RunRequest{PromptID: "alpha/shared", ProfileID: "root-only"}); !errors.Is(err, promptkit.ErrProfileNotFound) { t.Fatalf("root profile fallback error = %v, want ErrProfileNotFound", err) } unknown, err := engine.WithNamespaces(promptkit.Namespaces{Prompt: "not-configured"}) if err != nil { t.Fatalf("well-formed absent namespace rejected at view creation: %v", err) } if _, err := unknown.Prepare(context.Background(), promptkit.RunRequest{PromptID: "root-only", ProfileID: "alpha/shared"}); !errors.Is(err, promptkit.ErrPromptNotFound) { t.Fatalf("selection from absent namespace error = %v, want ErrPromptNotFound", err) } if _, err := scoped.Prepare(context.Background(), promptkit.RunRequest{PromptID: "alpha/beta/gamma", ProfileID: "alpha/shared"}); !errors.Is(err, promptkit.ErrInvalidRequest) { t.Fatalf("malformed caller prompt ID error = %v, want ErrInvalidRequest", err) } for _, invalid := range []promptkit.Namespaces{ {Prompt: "alpha/beta"}, {Profile: "/alpha"}, {Backend: " "}, } { if _, err := engine.WithNamespaces(invalid); !errors.Is(err, promptkit.ErrInvalidConfig) { t.Errorf("invalid namespaces %+v error = %v, want ErrInvalidConfig", invalid, err) } } if _, err := (*promptkit.Engine)(nil).WithNamespaces(promptkit.Namespaces{}); !errors.Is(err, promptkit.ErrInvalidConfig) { t.Fatalf("nil engine error = %v, want ErrInvalidConfig", err) } cleared, err := scoped.WithNamespaces(promptkit.Namespaces{}) if err != nil { t.Fatal(err) } if _, err := cleared.Prepare(context.Background(), promptkit.RunRequest{PromptID: "shared", ProfileID: "alpha/shared"}); !errors.Is(err, promptkit.ErrPromptNotFound) { t.Fatalf("cleared view unexpectedly retained prior scope: %v", err) } if _, err := scoped.Prepare(context.Background(), promptkit.RunRequest{PromptID: "shared", ProfileID: "shared"}); err != nil { t.Fatalf("replacing scopes mutated the prior view: %v", err) } } func TestWithNamespacesViewsCanPrepareConcurrently(t *testing.T) { engine := newNamespacedContractEngine(t, &fakeLLMClient{response: &promptkit.GenerateResponse{Content: "reply"}}) alpha, err := engine.WithNamespaces(promptkit.Namespaces{Prompt: "alpha", Profile: "alpha"}) if err != nil { t.Fatal(err) } beta, err := engine.WithNamespaces(promptkit.Namespaces{Prompt: "beta", Profile: "beta"}) if err != nil { t.Fatal(err) } var wait sync.WaitGroup for _, view := range []*promptkit.Engine{alpha, beta} { view := view wait.Add(1) go func() { defer wait.Done() prepared, err := view.Prepare(context.Background(), promptkit.RunRequest{PromptID: "shared", ProfileID: "shared"}) if err != nil { t.Errorf("concurrent prepare: %v", err) return } want := "alpha" if view == beta { want = "beta" } assertNamespacedSelection(t, prepared.PromptID, prepared.SelectedProfileID, prepared.SelectedBackendID, want) }() } wait.Wait() } func TestWithNamespacesRoutesInspectionsAndSmokeSelections(t *testing.T) { engine := newNamespacedContractEngine(t, &fakeLLMClient{response: &promptkit.GenerateResponse{Content: "reply"}}) scoped, err := engine.WithNamespaces(promptkit.Namespaces{ Prompt: "alpha", Profile: "beta", Backend: "alpha", }) if err != nil { t.Fatal(err) } prompt, err := scoped.InspectPrompt(context.Background(), "shared") if err != nil || prompt.PromptID != "alpha/shared" { t.Fatalf("scoped prompt inspection = %+v, error %v", prompt, err) } profile, err := scoped.InspectProfile(context.Background(), "shared") if err != nil || profile.ProfileID != "beta/shared" { t.Fatalf("scoped profile inspection = %+v, error %v", profile, err) } requirements, err := scoped.InspectRequirements(context.Background(), promptkit.RequirementInspectionRequest{ PromptID: "shared", ProfileID: "shared", }) if err != nil || requirements.PromptID != "alpha/shared" || requirements.ProfileID != "beta/shared" { t.Fatalf("scoped requirements inspection = %+v, error %v", requirements, err) } qualifiedPrompt, err := scoped.InspectPrompt(context.Background(), "beta/shared") if err != nil || qualifiedPrompt.PromptID != "beta/shared" { t.Fatalf("qualified prompt inspection = %+v, error %v", qualifiedPrompt, err) } // Explicit profile selection keeps precedence over the supplied backend, // while prompt, profile, and backend caller references are independently // validated/qualified. The profile's configured backend remains exact. report, err := scoped.SmokeTest(context.Background(), promptkit.SmokeTestRequest{ Kind: promptkit.SmokeTestReachability, PromptID: "shared", ProfileID: "shared", BackendID: "backend", }) if err != nil { t.Fatal(err) } if report.Target.PromptID != "alpha/shared" || report.Target.ProfileID != "beta/shared" || report.Target.BackendID != "beta/backend" || report.Target.SelectionSource != "profile" { t.Fatalf("scoped smoke selection = %+v", report.Target) } backendReport, err := scoped.SmokeTest(context.Background(), promptkit.SmokeTestRequest{ Kind: promptkit.SmokeTestReachability, BackendID: "backend", }) if err != nil { t.Fatal(err) } if backendReport.Target.BackendID != "alpha/backend" || backendReport.Target.SelectionSource != "backend" { t.Fatalf("scoped backend diagnostic selection = %+v", backendReport.Target) } defaultedReport, err := scoped.SmokeTest(context.Background(), promptkit.SmokeTestRequest{ Kind: promptkit.SmokeTestReachability, PromptID: "shared", }) if err != nil { t.Fatal(err) } if defaultedReport.Target.PromptID != "alpha/shared" || defaultedReport.Target.ProfileID != "root-only" || defaultedReport.Target.SelectionSource != "prompt" { t.Fatalf("configured prompt default was rewritten by scope: %+v", defaultedReport.Target) } for _, run := range []func() error{ func() error { _, err := scoped.InspectPrompt(context.Background(), "alpha/beta/shared"); return err }, func() error { _, err := scoped.InspectProfile(context.Background(), "alpha/beta/shared"); return err }, func() error { _, err := scoped.InspectRequirements(context.Background(), promptkit.RequirementInspectionRequest{ PromptID: "alpha/beta/shared", ProfileID: "shared", }) return err }, func() error { _, err := scoped.SmokeTest(context.Background(), promptkit.SmokeTestRequest{ Kind: promptkit.SmokeTestReachability, PromptID: "alpha/beta/shared", }) return err }, func() error { _, err := scoped.SmokeTest(context.Background(), promptkit.SmokeTestRequest{ Kind: promptkit.SmokeTestReachability, ProfileID: "alpha/beta/shared", }) return err }, func() error { _, err := scoped.SmokeTest(context.Background(), promptkit.SmokeTestRequest{ Kind: promptkit.SmokeTestReachability, ProfileID: "shared", BackendID: "alpha/beta/backend", }) return err }, } { if err := run(); !errors.Is(err, promptkit.ErrInvalidRequest) { t.Errorf("malformed supplied ID error = %v, want ErrInvalidRequest", err) } } if _, err := scoped.InspectPrompt(context.Background(), "missing"); !errors.Is(err, promptkit.ErrPromptNotFound) { t.Errorf("well-formed missing prompt error = %v, want ErrPromptNotFound", err) } } func newNamespacedContractEngine(t *testing.T, client promptkit.LLMClient) *promptkit.Engine { t.Helper() var inputs []configkit.Input for _, namespace := range []string{"alpha", "beta"} { endpoint := "https://" + namespace + ".example/v1" input, err := promptkit.CollectionInput(namespace, configkit.Mapping(namespace+" resources", map[string]any{ "backends": map[string]any{"backend": map[string]any{"endpoint": endpoint}}, "profiles": map[string]any{"shared": map[string]any{ "backend": namespace + "/backend", "model": namespace + "-model", }}, "prompts": map[string]any{"shared": map[string]any{ "version": "1", "default_profile": "root-only", "messages": []any{map[string]any{"role": "user", "content": "Hello"}}, "output": map[string]any{"format": "text", "validation_mode": "none"}, }}, })) if err != nil { t.Fatal(err) } input.Imports = false inputs = append(inputs, input) } inputs = append(inputs, configkit.Input{Source: configkit.Mapping("root resources", map[string]any{ "profiles": map[string]any{"root-only": map[string]any{ "endpoint": "https://root.example/v1", "model": "root-model", }}, "prompts": map[string]any{"root-only": map[string]any{ "version": "1", "messages": []any{map[string]any{"role": "user", "content": "Root prompt"}}, "output": map[string]any{"format": "text", "validation_mode": "none"}, }}, })}) engine, err := promptkit.NewEngine(promptkit.Config{Sources: promptkit.ConfigurationSources{ Underlays: []configkit.Underlay{{Inputs: inputs}}, }}, promptkit.WithLLMClient(client)) if err != nil { var loadErr *configkit.LoadError if errors.As(err, &loadErr) { t.Fatalf("construct namespaced engine: %v: %+v", err, loadErr.Diagnostics()) } t.Fatalf("construct namespaced engine: %v", err) } return engine } func assertNamespacedSelection(t *testing.T, promptID, profileID, backendID, namespace string) { t.Helper() if promptID != namespace+"/shared" || profileID != namespace+"/shared" || backendID != namespace+"/backend" { t.Fatalf("selected IDs = (%q, %q, %q), want namespace %q", promptID, profileID, backendID, namespace) } }