Wire embedded profile fallbacks
This commit is contained in:
@@ -45,6 +45,7 @@ func newAdapter(config Config, additionalOptions ...promptkit.Option) (*Adapter,
|
|||||||
options := []promptkit.Option{
|
options := []promptkit.Option{
|
||||||
promptkit.WithPromptFS(promptassets.PromptFS(), "."),
|
promptkit.WithPromptFS(promptassets.PromptFS(), "."),
|
||||||
promptkit.WithSchemaFS(promptassets.SchemaFS(), "."),
|
promptkit.WithSchemaFS(promptassets.SchemaFS(), "."),
|
||||||
|
promptkit.WithFallbackProfileFS(promptassets.ProfileFS(), "."),
|
||||||
}
|
}
|
||||||
if config.ProfileFile != "" {
|
if config.ProfileFile != "" {
|
||||||
options = append(options, promptkit.WithProfileFile(config.ProfileFile))
|
options = append(options, promptkit.WithProfileFile(config.ProfileFile))
|
||||||
|
|||||||
@@ -102,6 +102,99 @@ func TestInspectPromptAndProfile(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEmbeddedProfilesAreAvailableToProductionAndTestAdapters(t *testing.T) {
|
||||||
|
adapter, err := New(Config{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("New() error = %v", err)
|
||||||
|
}
|
||||||
|
for _, want := range []struct {
|
||||||
|
id string
|
||||||
|
backend string
|
||||||
|
model string
|
||||||
|
}{
|
||||||
|
{"weather-light", "openrouter", "deepseek/deepseek-v4-flash"},
|
||||||
|
{"weather-balanced", "openrouter", "~google/gemini-flash-latest"},
|
||||||
|
{"weather-deep", "openrouter", "~anthropic/claude-sonnet-latest"},
|
||||||
|
} {
|
||||||
|
t.Run(want.id, func(t *testing.T) {
|
||||||
|
assertProfile(t, adapter, want.id, want.backend, want.model)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
testAdapter, err := newAdapterForTest(Config{}, &fakeClient{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("newAdapterForTest() error = %v", err)
|
||||||
|
}
|
||||||
|
assertProfile(t, testAdapter, "weather-light", "openrouter", "deepseek/deepseek-v4-flash")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConfiguredProfilesOverrideEmbeddedFallbacks(t *testing.T) {
|
||||||
|
file := writeProfileFile(t, `id: weather-light
|
||||||
|
endpoint: https://local-file.example/v1
|
||||||
|
model: file-light
|
||||||
|
`)
|
||||||
|
fileAdapter, err := New(Config{ProfileFile: file})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("New(profile file) error = %v", err)
|
||||||
|
}
|
||||||
|
assertProfile(t, fileAdapter, "weather-light", "", "file-light")
|
||||||
|
|
||||||
|
directory := testProfileDirectory(t, `id: weather-light
|
||||||
|
backend: local
|
||||||
|
model: directory-light
|
||||||
|
`)
|
||||||
|
directoryAdapter, err := New(Config{ProfileDirectory: directory, LocalEndpoint: "https://local-directory.example/v1"})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("New(profile directory) error = %v", err)
|
||||||
|
}
|
||||||
|
assertProfile(t, directoryAdapter, "weather-light", promptkit.BackendLocal, "directory-light")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestProfileResolutionFallsThroughOnlyWhenTheConfiguredIDIsAbsent(t *testing.T) {
|
||||||
|
absentAdapter, err := New(Config{ProfileDirectory: testProfileDirectory(t, `id: other-profile
|
||||||
|
backend: openrouter
|
||||||
|
model: other-model
|
||||||
|
`)})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("New(absent profile) error = %v", err)
|
||||||
|
}
|
||||||
|
assertProfile(t, absentAdapter, "weather-light", "openrouter", "deepseek/deepseek-v4-flash")
|
||||||
|
|
||||||
|
malformedAdapter, err := New(Config{ProfileDirectory: testProfileDirectory(t, `id: weather-light
|
||||||
|
backend: openrouter
|
||||||
|
`)})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("New(malformed profile) error = %v", err)
|
||||||
|
}
|
||||||
|
if _, err := malformedAdapter.InspectProfile(context.Background(), "weather-light"); err == nil {
|
||||||
|
t.Fatal("InspectProfile() error = nil, want malformed configured profile error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestProfileResolutionPreservesBuiltInAndExplicitPrecedence(t *testing.T) {
|
||||||
|
adapter, err := New(Config{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("New() error = %v", err)
|
||||||
|
}
|
||||||
|
builtin, err := adapter.InspectProfile(context.Background(), "gemini-flash-latest")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("InspectProfile(builtin) error = %v", err)
|
||||||
|
}
|
||||||
|
if builtin.ProfileID != "gemini-flash-latest" || builtin.BackendID != "openrouter" || builtin.ModelName == "" {
|
||||||
|
t.Fatalf("builtin profile = %#v", builtin)
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit, err := newAdapter(Config{}, promptkit.WithProfiles(promptkit.Profile{
|
||||||
|
ID: "weather-light",
|
||||||
|
Endpoint: "https://explicit.example/v1",
|
||||||
|
Model: "explicit-light",
|
||||||
|
}))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("newAdapter(explicit profile) error = %v", err)
|
||||||
|
}
|
||||||
|
assertProfile(t, explicit, "weather-light", "", "explicit-light")
|
||||||
|
}
|
||||||
|
|
||||||
func TestExecuteUsesPreparedInlineDataPackage(t *testing.T) {
|
func TestExecuteUsesPreparedInlineDataPackage(t *testing.T) {
|
||||||
client := &fakeClient{response: validResponse()}
|
client := &fakeClient{response: validResponse()}
|
||||||
adapter := newTestAdapter(t, client)
|
adapter := newTestAdapter(t, client)
|
||||||
@@ -339,6 +432,17 @@ func newTestAdapter(t *testing.T, client promptkit.LLMClient) *Adapter {
|
|||||||
return newTestAdapterWithOptions(t, client)
|
return newTestAdapterWithOptions(t, client)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func assertProfile(t *testing.T, adapter *Adapter, id string, backend string, model string) {
|
||||||
|
t.Helper()
|
||||||
|
profile, err := adapter.InspectProfile(context.Background(), id)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("InspectProfile(%q) error = %v", id, err)
|
||||||
|
}
|
||||||
|
if profile.ProfileID != id || profile.BackendID != backend || profile.ModelName != model {
|
||||||
|
t.Fatalf("profile = %#v, want %q with backend/model %q/%q", profile, id, backend, model)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func newTestAdapterWithOptions(t *testing.T, client promptkit.LLMClient, options ...promptkit.Option) *Adapter {
|
func newTestAdapterWithOptions(t *testing.T, client promptkit.LLMClient, options ...promptkit.Option) *Adapter {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
profiles := testProfileDirectory(t, `id: test-profile
|
profiles := testProfileDirectory(t, `id: test-profile
|
||||||
@@ -366,6 +470,15 @@ func testProfileDirectory(t *testing.T, profile string) string {
|
|||||||
return profiles
|
return profiles
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func writeProfileFile(t *testing.T, profile string) string {
|
||||||
|
t.Helper()
|
||||||
|
path := filepath.Join(t.TempDir(), "profile.yml")
|
||||||
|
if err := os.WriteFile(path, []byte(profile), 0o600); err != nil {
|
||||||
|
t.Fatalf("write profile: %v", err)
|
||||||
|
}
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
func testExecuteRequest() promptexec.ExecuteRequest {
|
func testExecuteRequest() promptexec.ExecuteRequest {
|
||||||
return promptexec.ExecuteRequest{
|
return promptexec.ExecuteRequest{
|
||||||
PromptID: "weather.daily_generated_text",
|
PromptID: "weather.daily_generated_text",
|
||||||
|
|||||||
Reference in New Issue
Block a user