package configuration import ( "context" "fmt" "gitea.maximumdirect.net/eric/promptkit/internal/backend" "gitea.maximumdirect.net/eric/promptkit/internal/defaults" "gitea.maximumdirect.net/eric/promptkit/internal/domain" "gitea.maximumdirect.net/eric/promptkit/internal/jsonvalue" profilepkg "gitea.maximumdirect.net/eric/promptkit/internal/profile" ) func (state *loaded) buildExecutionProfiles() error { backendConfigs := indexedBackends(&state.result.Config) profileConfigs := indexedProfiles(&state.result.Config) definitions := make(map[string]domain.Backend, len(backendConfigs)) for _, id := range sortedKeys(backendConfigs) { config := backendConfigs[id] definition := domain.Backend{ID: id, ExtraParams: config.ExtraParams} if config.SmokeTests != nil { smokeTests := &domain.BackendSmokeTestConfig{DefaultProfile: config.SmokeTests.DefaultProfile} if config.SmokeTests.Reachability != nil { smokeTests.Reachability = &domain.ReachabilityProbeConfig{Endpoint: config.SmokeTests.Reachability.Endpoint} } if config.SmokeTests.Authentication != nil { smokeTests.Authentication = &domain.AuthenticationProbeConfig{ Kind: config.SmokeTests.Authentication.Kind, Endpoint: config.SmokeTests.Authentication.Endpoint, } } definition.SmokeTests = smokeTests } if config.Endpoint != nil { definition.Endpoint = *config.Endpoint } if config.APIKeyEnv != nil { definition.APIKeyEnv = *config.APIKeyEnv } if config.ConcurrencyLimit != nil { definition.ConcurrencyLimit = *config.ConcurrencyLimit } if config.QueueCapacity != nil { definition.QueueCapacity = *config.QueueCapacity definition.QueueCapacitySet = definition.ConcurrencyLimit > 0 } definitions[id] = definition } registry, err := backend.NewEffectiveRegistry(definitions) if err != nil { return err } state.registry = registry state.indexedProfiles = make(map[string]domain.ExecutionProfile, len(profileConfigs)) for _, id := range sortedKeys(profileConfigs) { config := profileConfigs[id] fields := state.profiles[id] target := defaults.ExecutionTargetDefault() if config.Backend != nil && *config.Backend != "" { selected, err := registry.GetBackend(*config.Backend) if err != nil { return fmt.Errorf("profile %q backend: %w", id, err) } target.BackendID = selected.ID target.Endpoint = selected.Endpoint target.APIKeyEnv = selected.APIKeyEnv target.ExtraParams = selected.ExtraParams } presence := domain.ExecutionTargetPresence{} if fields["endpoint"] != fieldAbsent { target.Endpoint = valueOrZero(config.Endpoint) } if fields["model"] != fieldAbsent { target.Model = valueOrZero(config.Model) } if fields["temperature"] != fieldAbsent { target.Temperature = valueOrZero(config.Temperature) presence.Temperature = fields["temperature"] == fieldValue } if fields["top_p"] != fieldAbsent { target.TopP = valueOrZero(config.TopP) presence.TopP = fields["top_p"] == fieldValue } if fields["max_tokens"] != fieldAbsent { target.MaxTokens = valueOrZero(config.MaxTokens) presence.MaxTokens = fields["max_tokens"] == fieldValue } if fields["timeout_seconds"] == fieldValue { target.TimeoutSeconds = valueOrZero(config.TimeoutSeconds) presence.TimeoutSeconds = true } if fields["service_tier"] != fieldAbsent { target.ServiceTier = valueOrZero(config.ServiceTier) } if fields["reasoning_effort"] != fieldAbsent { target.ReasoningEffort = valueOrZero(config.ReasoningEffort) } if fields["api_key_env"] != fieldAbsent { target.APIKeyEnv = valueOrZero(config.APIKeyEnv) } if fields["api_key_required"] != fieldAbsent { target.APIKeyRequired = valueOrZero(config.APIKeyRequired) } if target.APIKeyRequired && fields["api_key_env"] == fieldAbsent { target.APIKeyEnv = "" } switch fields["extra_params"] { case fieldNull: target.ExtraParams = nil case fieldValue: merged, err := overlayProviderMap(target.ExtraParams, config.ExtraParams) if err != nil { return fmt.Errorf("profile %q extra parameters: %w", id, err) } target.ExtraParams = merged } profile := domain.ExecutionProfile{ID: id, ResolvedTarget: &target, TargetPresence: presence} state.indexedProfiles[id] = profile } return nil } func valueOrZero[T any](value *T) T { if value == nil { var zero T return zero } return *value } // overlayProviderMap applies only the backend-to-profile JSON-object default // merge. ConfigKit has already resolved source layering and inheritance. func overlayProviderMap(lower, upper map[string]any) (map[string]any, error) { merged, err := jsonvalue.CopyMap(lower) if err != nil { return nil, err } if merged == nil { merged = make(map[string]any) } for key, value := range upper { if child, ok := value.(map[string]any); ok { if existing, ok := merged[key].(map[string]any); ok { combined, err := overlayProviderMap(existing, child) if err != nil { return nil, err } merged[key] = combined continue } } copied, err := jsonvalue.Copy(value) if err != nil { return nil, err } merged[key] = copied } return merged, nil } func (state *loaded) lookupProfile(ctx context.Context, id string) (domain.ExecutionProfile, error) { if err := ctx.Err(); err != nil { return domain.ExecutionProfile{}, err } if state == nil { return domain.ExecutionProfile{}, fmt.Errorf("%w: %q", profilepkg.ErrProfileNotFound, id) } profile, found := state.indexedProfiles[id] if !found { return domain.ExecutionProfile{}, fmt.Errorf("%w: %q", profilepkg.ErrProfileNotFound, id) } return profile, nil } // GetProfile returns an independently owned indexed profile for the internal // runner's lookup boundary. func (state *loaded) GetProfile(ctx context.Context, id string) (*domain.ExecutionProfile, error) { profile, err := state.lookupProfile(ctx, id) if err != nil { return nil, err } target := *profile.ResolvedTarget params, err := jsonvalue.CopyMap(target.ExtraParams) if err != nil { return nil, err } target.ExtraParams = params profile.ResolvedTarget = &target return &profile, nil } // GetProfileIdentity returns the exact lookup ID for a captured profile // without copying its execution target. func (state *loaded) GetProfileIdentity(ctx context.Context, id string) (string, error) { if _, err := state.lookupProfile(ctx, id); err != nil { return "", err } return id, nil } // GetBackend returns an independently owned effective backend definition. func (state *loaded) GetBackend(id string) (domain.Backend, error) { if state == nil { return domain.Backend{}, fmt.Errorf("backend registry is not configured") } return state.registry.GetBackend(id) } // CapacityPolicies returns the selected backend admission policies. func (state *loaded) CapacityPolicies() map[string]domain.BackendCapacityPolicy { if state == nil { return nil } return state.registry.CapacityPolicies() }