package promptkit_test import ( "context" "errors" "net/http" "reflect" "strings" "testing" "go.maximumdirect.net/configkit" "go.maximumdirect.net/promptkit" ) type rejectBundleTransport struct{} func (rejectBundleTransport) RoundTrip(*http.Request) (*http.Response, error) { return nil, errors.New("unexpected HTTP request") } func TestBundledOpenRouterOptionsAndInventory(t *testing.T) { t.Setenv("OPENROUTER_API_KEY", "") for _, test := range []struct { name string options []promptkit.Option enabled bool }{ {"default", nil, true}, {"enabled", []promptkit.Option{promptkit.WithBundledOpenRouter(true)}, true}, {"disabled", []promptkit.Option{promptkit.WithBundledOpenRouter(false)}, false}, {"last disables", []promptkit.Option{promptkit.WithBundledOpenRouter(true), promptkit.WithBundledOpenRouter(false)}, false}, {"last enables", []promptkit.Option{promptkit.WithBundledOpenRouter(false), promptkit.WithBundledOpenRouter(true)}, true}, } { t.Run(test.name, func(t *testing.T) { engine, err := promptkit.NewEngine(promptkit.Config{HTTPClient: &http.Client{Transport: rejectBundleTransport{}}}, test.options...) if err != nil { t.Fatal(err) } profiles, err := engine.ListProfiles(context.Background()) if err != nil { t.Fatal(err) } backends, err := engine.ListBackends(context.Background()) if err != nil { t.Fatal(err) } prompts, err := engine.ListPrompts(context.Background()) if err != nil { t.Fatal(err) } collections, err := engine.ListCollections(context.Background()) if err != nil { t.Fatal(err) } want := 0 if test.enabled { want = 17 } if len(profiles) != want || len(backends) != boolCount(test.enabled) || len(prompts) != 0 || len(collections) != 0 { t.Fatalf("inventories: %v %v %v %v", profiles, backends, prompts, collections) } if test.enabled { wantProfiles := []string{"auto", "auto-high", "auto-low", "auto-max", "auto-medium", "auto-xhigh", "claude-fable-latest", "claude-haiku-latest", "claude-opus-latest", "claude-sonnet-latest", "free", "gemini-flash-latest", "gemini-pro-latest", "gpt-astra-latest", "gpt-luna-latest", "gpt-sol-latest", "gpt-terra-latest"} if !reflect.DeepEqual(profiles, wantProfiles) || !reflect.DeepEqual(backends, []string{"openrouter"}) { t.Fatalf("bundle inventory: %v %v", profiles, backends) } for id, model := range map[string]string{"auto": "openrouter/auto", "auto-max": "openrouter/auto", "gpt-luna-latest": "~openai/gpt-luna-latest", "free": "openrouter/free"} { profile, err := engine.InspectProfile(context.Background(), id) if err != nil || profile.EffectiveModelParams.Model != model || profile.EffectiveModelParams.BackendID != "openrouter" { t.Fatalf("profile %s = %+v, %v", id, profile, err) } } view, err := engine.InspectConfiguration() if err != nil { t.Fatal(err) } if !strings.Contains(fmtSources(view.Sources()), "Promptkit bundled OpenRouter") { t.Fatal("bundle source missing") } if explanation, found := view.Explain(configkit.Keys("backends").Index(0).Key("endpoint")); !found || !strings.Contains(explanation.Effective.YAML, "https://openrouter.ai/api/v1") || len(explanation.History) == 0 { t.Fatalf("bundle explanation = %+v", explanation) } } }) } } func boolCount(value bool) int { if value { return 1 } return 0 } func fmtSources(sources []configkit.SourceInfo) string { var b strings.Builder for _, source := range sources { b.WriteString(source.Label) } return b.String() } func TestBundlePreservesCallerUnderlayBackingArray(t *testing.T) { source := configkit.Mapping("caller", map[string]any{"profiles": []any{map[string]any{"id": "caller", "model": "model"}}}) groups := make([]configkit.Underlay, 1, 2) groups[0] = configkit.Underlay{Inputs: []configkit.Input{{Source: source}}} before := append([]configkit.Underlay(nil), groups...) if _, err := promptkit.NewEngine(promptkit.Config{Sources: promptkit.ConfigurationSources{Underlays: groups}}); err != nil { t.Fatal(err) } if !reflect.DeepEqual(groups, before) || !reflect.DeepEqual(groups[:2][1], configkit.Underlay{}) { t.Fatal("caller underlays were modified") } } func TestDisabledBundleKeepsCallerOpenRouter(t *testing.T) { input := configkit.Input{Source: configkit.Mapping("caller", map[string]any{"backends": []any{map[string]any{"id": "openrouter", "endpoint": "https://local.invalid/v1"}}})} engine, err := promptkit.NewEngine(promptkit.Config{Sources: promptkit.ConfigurationSources{Main: &input}}, promptkit.WithBundledOpenRouter(false)) if err != nil { t.Fatal(err) } backends, err := engine.ListBackends(context.Background()) if err != nil || !reflect.DeepEqual(backends, []string{"openrouter"}) { t.Fatalf("backends = %v, %v", backends, err) } }