package domain import ( "time" "gitea.maximumdirect.net/eric/promptkit/internal/jsonvalue" ) // BackendSmokeTestConfig describes optional backend-owned diagnostic defaults. type BackendSmokeTestConfig struct { DefaultProfile *string Reachability *ReachabilityProbeConfig Authentication *AuthenticationProbeConfig } // ReachabilityProbeConfig describes an optional endpoint for reachability tests. type ReachabilityProbeConfig struct { Endpoint *string } // AuthenticationProbeConfig describes an optional authentication diagnostic. type AuthenticationProbeConfig struct { Kind *string Endpoint *string } // SmokeTestKind identifies one built-in diagnostic operation. type SmokeTestKind string const ( SmokeTestReachability SmokeTestKind = "reachability" SmokeTestAuthentication SmokeTestKind = "authentication" SmokeTestTextInference SmokeTestKind = "text_inference" SmokeTestStructuredOutput SmokeTestKind = "structured_output" ) // SmokeTestRequest selects one diagnostic and its execution target. type SmokeTestRequest struct { Kind SmokeTestKind BackendID string PromptID string PromptVersion string ProfileID string Execution *ExecutionTargetOverride APIKey string `json:"-" yaml:"-"` TransientRetries *int } // SmokeTestReport contains factual diagnostic results, not generated content. type SmokeTestReport struct { Kind SmokeTestKind Supported bool Applicable *bool Completed bool Reason SmokeTestReason Target SmokeTestTarget Facts SmokeTestFacts Timing SmokeTestTiming Attempts []SmokeTestAttempt Usage ObservedTokenUsage Failure ExecutionFailureKind } // SmokeTestTarget identifies the selected diagnostic target and its settings. type SmokeTestTarget struct { BackendID string ProfileID string PromptID string PromptVersion string DefaultSourceBackendID string SelectionSource string Endpoint string EffectiveSettings ExecutionTarget SettingsPresence ExecutionTargetPresence } // SmokeTestFacts contains optional factual observations from a diagnostic. type SmokeTestFacts struct { CredentialsSupplied *bool EndpointReachable *bool CredentialsAccepted *bool ResponseReceived *bool GenerationCompleted *bool TextReturned *bool ExpectedTextMatched *bool StructuredOutputRequested *bool ValidJSON *bool SchemaMatched *bool } // SmokeTestTiming records elapsed diagnostic and phase durations. type SmokeTestTiming struct { StartedAt time.Time Duration time.Duration CapacityWait *time.Duration RequestDuration *time.Duration RetryDelay *time.Duration EvaluationDuration *time.Duration } // SmokeTestAttempt records one dispatched attempt or an interrupted acquisition. type SmokeTestAttempt struct { Dispatched bool InitialEndpoint string Endpoint string HTTPStatus *int Facts SmokeTestFacts Timing SmokeTestTiming Failure ExecutionFailureKind Usage ObservedTokenUsage } // SmokeTestReason identifies additional factual context for a diagnostic. type SmokeTestReason string const ( SmokeTestReasonNone SmokeTestReason = "" SmokeTestReasonAuthenticationNotApplicable SmokeTestReason = "authentication_not_applicable" SmokeTestReasonProbeNotConfigured SmokeTestReason = "probe_not_configured" SmokeTestReasonHTTPDiagnosticsUnavailable SmokeTestReason = "http_diagnostics_unavailable" SmokeTestReasonRequiredCredentialMissing SmokeTestReason = "required_credential_missing" SmokeTestReasonAuthenticationResponseUnrecognized SmokeTestReason = "authentication_response_unrecognized" ) // CloneBackend returns a copy of a backend, including its mutable settings. func CloneBackend(backend Backend) (Backend, error) { cloned := backend var err error cloned.ExtraParams, err = jsonvalue.CopyMap(backend.ExtraParams) if err != nil { return Backend{}, err } cloned.SmokeTests = CloneBackendSmokeTestConfig(backend.SmokeTests) return cloned, nil } // CloneBackendSmokeTestConfig returns an independent copy of optional metadata. func CloneBackendSmokeTestConfig(config *BackendSmokeTestConfig) *BackendSmokeTestConfig { if config == nil { return nil } cloned := *config cloned.DefaultProfile = cloneString(config.DefaultProfile) if config.Reachability != nil { reachability := *config.Reachability reachability.Endpoint = cloneString(config.Reachability.Endpoint) cloned.Reachability = &reachability } if config.Authentication != nil { authentication := *config.Authentication authentication.Kind = cloneString(config.Authentication.Kind) authentication.Endpoint = cloneString(config.Authentication.Endpoint) cloned.Authentication = &authentication } return &cloned } // CloneSmokeTestRequest returns a copy that owns its optional settings. func CloneSmokeTestRequest(request SmokeTestRequest) (SmokeTestRequest, error) { cloned := request cloned.TransientRetries = cloneInt(request.TransientRetries) if request.Execution == nil { return cloned, nil } execution := *request.Execution execution.Temperature = cloneFloat64(request.Execution.Temperature) execution.MaxTokens = cloneInt(request.Execution.MaxTokens) execution.TopP = cloneFloat64(request.Execution.TopP) execution.TimeoutSeconds = cloneInt(request.Execution.TimeoutSeconds) execution.ReasoningEffort = cloneString(request.Execution.ReasoningEffort) var err error execution.ExtraParams, err = jsonvalue.CopyMap(request.Execution.ExtraParams) if err != nil { return SmokeTestRequest{}, err } cloned.Execution = &execution return cloned, nil } // CloneSmokeTestReport returns a copy with independent optional facts and maps. func CloneSmokeTestReport(report SmokeTestReport) (SmokeTestReport, error) { cloned := report cloned.Applicable = cloneBool(report.Applicable) cloned.Facts = cloneSmokeTestFacts(report.Facts) cloned.Timing = cloneSmokeTestTiming(report.Timing) var err error cloned.Target.EffectiveSettings.ExtraParams, err = jsonvalue.CopyMap(report.Target.EffectiveSettings.ExtraParams) if err != nil { return SmokeTestReport{}, err } if report.Attempts != nil { cloned.Attempts = make([]SmokeTestAttempt, len(report.Attempts)) for index, attempt := range report.Attempts { cloned.Attempts[index] = attempt cloned.Attempts[index].HTTPStatus = cloneInt(attempt.HTTPStatus) cloned.Attempts[index].Facts = cloneSmokeTestFacts(attempt.Facts) cloned.Attempts[index].Timing = cloneSmokeTestTiming(attempt.Timing) } } return cloned, nil } func cloneSmokeTestFacts(facts SmokeTestFacts) SmokeTestFacts { facts.CredentialsSupplied = cloneBool(facts.CredentialsSupplied) facts.EndpointReachable = cloneBool(facts.EndpointReachable) facts.CredentialsAccepted = cloneBool(facts.CredentialsAccepted) facts.ResponseReceived = cloneBool(facts.ResponseReceived) facts.GenerationCompleted = cloneBool(facts.GenerationCompleted) facts.TextReturned = cloneBool(facts.TextReturned) facts.ExpectedTextMatched = cloneBool(facts.ExpectedTextMatched) facts.StructuredOutputRequested = cloneBool(facts.StructuredOutputRequested) facts.ValidJSON = cloneBool(facts.ValidJSON) facts.SchemaMatched = cloneBool(facts.SchemaMatched) return facts } func cloneSmokeTestTiming(timing SmokeTestTiming) SmokeTestTiming { timing.CapacityWait = cloneDuration(timing.CapacityWait) timing.RequestDuration = cloneDuration(timing.RequestDuration) timing.RetryDelay = cloneDuration(timing.RetryDelay) timing.EvaluationDuration = cloneDuration(timing.EvaluationDuration) return timing } func cloneBool(value *bool) *bool { if value == nil { return nil } cloned := *value return &cloned } func cloneDuration(value *time.Duration) *time.Duration { if value == nil { return nil } cloned := *value return &cloned } func cloneFloat64(value *float64) *float64 { if value == nil { return nil } cloned := *value return &cloned } func cloneInt(value *int) *int { if value == nil { return nil } cloned := *value return &cloned } func cloneString(value *string) *string { if value == nil { return nil } cloned := *value return &cloned }