package promptkit import ( "gitea.maximumdirect.net/eric/promptkit/internal/domain" ) // OpenAICompatibleProfile returns an in-memory Profile for an OpenAI-compatible // chat-completions endpoint. A non-blank BaseProfileID permits its target // fields to be inherited when the profile is selected or inspected. // // It does not register global state, maintain a model catalog, or resolve // credentials. If APIKeyRequired is true, callers satisfy it with // RunRequest.APIKey or an explicit request ExecutionTargetOverride.APIKeyEnv. // Raw API keys do not belong in profiles. // // The function copies the ExtraParams map itself but does not recursively copy // nested values. Validation and a deep copy occur when NewEngine applies a // WithProfiles option containing the returned Profile. func OpenAICompatibleProfile(cfg OpenAICompatibleProfileConfig) Profile { return Profile{ ID: cfg.ID, BaseProfileID: cfg.BaseProfileID, BackendID: cfg.BackendID, Endpoint: cfg.Endpoint, Model: cfg.Model, Temperature: cfg.Temperature, MaxTokens: cfg.MaxTokens, TopP: cfg.TopP, TimeoutSeconds: cfg.TimeoutSeconds, ServiceTier: cfg.ServiceTier, ReasoningEffort: cfg.ReasoningEffort, APIKeyRequired: cfg.APIKeyRequired, ExtraParams: copyShallowAnyMap(cfg.ExtraParams), } } func copyShallowAnyMap(src map[string]any) map[string]any { if src == nil { return nil } out := make(map[string]any, len(src)) for k, v := range src { out[k] = v } return out } func toDomainProfile(publicProfile Profile) domain.ExecutionProfile { return domain.ExecutionProfile{ ID: publicProfile.ID, BaseProfileID: publicProfile.BaseProfileID, BackendID: publicProfile.BackendID, Endpoint: publicProfile.Endpoint, Model: publicProfile.Model, Temperature: publicProfile.Temperature, MaxTokens: publicProfile.MaxTokens, TopP: publicProfile.TopP, TimeoutSeconds: publicProfile.TimeoutSeconds, ServiceTier: publicProfile.ServiceTier, ReasoningEffort: publicProfile.ReasoningEffort, APIKeyRequired: publicProfile.APIKeyRequired, ExtraParams: publicProfile.ExtraParams, } }