Files
ttstd-infinite-canvas/backend/internal/app/platform_bridge.go

236 lines
7.6 KiB
Go

package app
import (
"context"
"net/http"
"time"
"yingce/backend/internal/kernel"
"yingce/backend/internal/model"
"yingce/backend/internal/platform"
)
type (
RuntimeResourcePolicy = platform.RuntimeResourcePolicy
RuntimeStoragePolicy = platform.RuntimeStoragePolicy
RuntimeTaskPolicy = platform.RuntimeTaskPolicy
RuntimeRequestPolicy = platform.RuntimeRequestPolicy
RuntimePolicySetting = platform.RuntimePolicySetting
PublicRuntimePolicySetting = platform.PublicRuntimePolicySetting
PublicRuntimeLimits = platform.PublicRuntimeLimits
FeatureAvailability = platform.FeatureAvailability
PublicFeatureAvailability = platform.PublicFeatureAvailability
)
const (
FeatureShortDrama = platform.FeatureShortDrama
FeatureTaskCenter = platform.FeatureTaskCenter
FeatureCredits = platform.FeatureCredits
FeatureCustomChannels = platform.FeatureCustomChannels
FeatureFrontendModels = platform.FeatureFrontendModels
FeaturePluginCenter = platform.FeaturePluginCenter
FeatureSystemPlugins = platform.FeatureSystemPlugins
FeatureInspirationSources = platform.FeatureInspirationSources
FeatureTimelineTranscription = platform.FeatureTimelineTranscription
FeatureImageWorkbench = platform.FeatureImageWorkbench
FeatureVideoWorkbench = platform.FeatureVideoWorkbench
)
type platformHost struct {
svc *Service
}
func (h platformHost) RequireAdmin(user *model.User) error {
if h.svc == nil {
return nil
}
return h.svc.RequireAdmin(user)
}
func (h platformHost) AppendAudit(actor *model.User, action, targetType, targetID, summary string, metadata any) error {
if h.svc == nil {
return nil
}
return h.svc.appendAdminAudit(actor, action, targetType, targetID, summary, metadata)
}
func (h platformHost) ChannelConcurrencyLimit(channelID string) (int, error) {
if h.svc == nil {
return 0, nil
}
channel, err := h.svc.repo.SystemChannel(channelID)
if err != nil {
return 0, err
}
return channel.ConcurrencyLimit, nil
}
func (s *Service) platformDomain() *platform.Service {
if s == nil {
return platform.New(nil, nil, nil)
}
if s.platform != nil {
return s.platform
}
// Tests and small embedded callers may construct Service literals instead
// of using New. Cache the lazily-created domain so its bounded read caches
// retain their intended lifetime and do not turn every read into a DB hit.
s.workerRuntimeMu.Lock()
defer s.workerRuntimeMu.Unlock()
if s.platform == nil {
s.platform = platform.New(s.repo, s.coordinator, platformHost{svc: s})
}
return s.platform
}
func (s *Service) RuntimePolicy() (RuntimePolicySetting, error) {
return s.platformDomain().RuntimePolicy()
}
func (s *Service) runtimeConcurrencySetting() (RuntimeTaskPolicy, error) {
return s.platformDomain().RuntimeConcurrencySetting()
}
func (s *Service) PublicRuntimeLimits() (*PublicRuntimeLimits, error) {
return s.platformDomain().PublicRuntimeLimits()
}
func (s *Service) AdminRuntimePolicySetting(actor *model.User) (*PublicRuntimePolicySetting, error) {
return s.platformDomain().AdminRuntimePolicySetting(actor)
}
func (s *Service) AdminSelfUseRuntimePolicy(actor *model.User) (*PublicRuntimePolicySetting, error) {
return s.platformDomain().AdminSelfUseRuntimePolicy(actor)
}
func (s *Service) UpdateRuntimePolicySetting(actor *model.User, value RuntimePolicySetting) (*PublicRuntimePolicySetting, error) {
return s.platformDomain().UpdateRuntimePolicySetting(actor, value)
}
func (s *Service) ResetRuntimePolicySetting(actor *model.User) (*PublicRuntimePolicySetting, error) {
return s.platformDomain().ResetRuntimePolicySetting(actor)
}
func (s *Service) FeatureAvailability() (*PublicFeatureAvailability, error) {
return s.platformDomain().FeatureAvailability()
}
func (s *Service) AdminFeatureAvailability(actor *model.User) (*PublicFeatureAvailability, error) {
return s.platformDomain().AdminFeatureAvailability(actor)
}
func (s *Service) UpdateFeatureAvailability(actor *model.User, value FeatureAvailability) (*PublicFeatureAvailability, error) {
return s.platformDomain().UpdateFeatureAvailability(actor, value)
}
func (s *Service) FeatureEnabled(feature string) (bool, error) {
return s.platformDomain().FeatureEnabled(feature)
}
func (s *Service) RequireFeature(feature string) error {
return s.platformDomain().RequireFeature(feature)
}
func (s *Service) AcquireChannelSlot(ctx context.Context, channelID string, fallbackScope string, ttl time.Duration) (func(), int, error) {
return s.platformDomain().AcquireChannelSlot(ctx, channelID, fallbackScope, ttl)
}
func (s *Service) AllowRequest(ctx context.Context, key string, limit int, window time.Duration) (bool, error) {
return s.platformDomain().AllowRequest(ctx, key, limit, window)
}
func (s *Service) RequestRetryAfter(ctx context.Context, key string, window time.Duration) time.Duration {
return s.platformDomain().RequestRetryAfter(ctx, key, window)
}
func (s *Service) AcquireCustomRelaySlot(ctx context.Context, userID string, limit int, ttl time.Duration) (func(), bool, error) {
return s.platformDomain().AcquireCustomRelaySlot(ctx, userID, limit, ttl)
}
func (s *Service) RecordChannelResult(ctx context.Context, channelID string, failed bool) error {
return s.platformDomain().RecordChannelResult(ctx, channelID, failed)
}
func (s *Service) Close() error {
if s == nil {
return nil
}
s.closeCloudAgentPiRunners()
s.closeApprovedCloudAgentMediaWaiters()
if s.coordinator == nil {
return nil
}
if !s.coordinator.HasRedis() {
return nil
}
return s.coordinator.Redis().Close()
}
func ChannelSlotFailureDetails(err error) (string, string) {
return platform.ChannelSlotFailureDetails(err)
}
func SanitizeAPICallPayload(data []byte, contentType string) string {
return platform.SanitizeAPICallPayload(data, contentType)
}
func optionalJSONString(payload map[string]any, key string) (string, error) {
return platform.OptionalJSONString(payload, key)
}
func requireJSONString(payload map[string]any, key string) (string, error) {
return platform.RequireJSONString(payload, key)
}
func firstJSONString(payload map[string]any, keys ...string) (string, error) {
return platform.FirstJSONString(payload, keys...)
}
func megabytes(value int64) int64 { return kernel.Megabytes(value) }
func gigabytes(value int64) int64 { return kernel.Gigabytes(value) }
func requestPayloadForLog(req *http.Request) string {
return platform.RequestPayloadForLog(req)
}
func (s *Service) ValidateRuntime() error {
if s == nil {
return nil
}
if s.pluginRuntimeErr != nil {
return s.pluginRuntimeErr
}
return s.runtimeErr
}
const (
featureAvailabilitySettingKey = "feature_availability"
runtimePolicySettingKey = "runtime_policy"
)
func defaultFeatureAvailability() FeatureAvailability {
return platform.DefaultFeatureAvailability()
}
func publicFeatureAvailability(setting *model.SystemSetting, value FeatureAvailability) *PublicFeatureAvailability {
return platform.ProjectFeatureAvailability(setting, value)
}
func selfUseRuntimePolicy() RuntimePolicySetting { return platform.SelfUseRuntimePolicy() }
func validateRuntimePolicy(value RuntimePolicySetting) error {
return platform.ValidateRuntimePolicy(value)
}
// Keep package-local test and legacy helpers source-compatible while the
// runtime policy implementation lives in internal/platform.
func defaultRuntimePolicy() RuntimePolicySetting {
return platform.DefaultRuntimePolicy()
}
const (
minChannelConcurrencyLimit = platform.MinChannelConcurrencyLimit
maxChannelConcurrencyLimit = platform.MaxChannelConcurrencyLimit
runtimeCoordinationTimeout = platform.CoordinationTimeout
routeCatalogVersionKey = platform.RouteCatalogVersionKey
)