修改配置编辑不了的问题

This commit is contained in:
andy committed 2026-08-18 12:41:39 +08:00
1 parent 22b504e53e
commit 2a2f78c81e
42 files changed
+1082 -178

No files matched your search

+105 -28
View File
@@ -59,10 +59,6 @@ func parseBool(value string) bool {
}
}
func allowUnconfiguredProviders(getenv postgres.Getenv) bool {
return parseBool(getenv("ZHINIAN_ALLOW_UNCONFIGURED_PROVIDERS"))
}
func applicationJobID() string {
return applicationID("job")
}
@@ -143,6 +139,10 @@ func bailianNativeBaseURL(getenv postgres.Getenv) string {
func buildProviderRegistry(getenv postgres.Getenv) jobs.ProviderRegistry {
client := &http.Client{Timeout: durationEnv(getenv, "ZHINIAN_PROVIDER_TIMEOUT_MS", 30*time.Second)}
maximum := positiveInt64Env(getenv, "ZHINIAN_PROVIDER_MAX_RESPONSE_BYTES", 2<<20)
return buildProviderRegistryWithClient(getenv, client, maximum)
}
func buildProviderRegistryWithClient(getenv postgres.Getenv, client *http.Client, maximum int64) jobs.ProviderRegistry {
return jobs.ProviderRegistry{
"volcengine-visual": providers.NewVolcengine(providers.Config{
BaseURL: firstNonEmpty(getenv("VOLCENGINE_VISUAL_ENDPOINT"), "https://visual.volcengineapi.com"),
@@ -164,6 +164,7 @@ func providerImageTargets(getenv postgres.Getenv) map[string]jobs.ProviderTarget
"evolink": {
Provider: "evolink",
Model: firstNonEmpty(getenv("EVOLINK_IMAGE_MODEL"), "gpt-image-2"),
Settings: map[string]any{"quality": firstNonEmpty(getenv("EVOLINK_IMAGE_QUALITY"), "medium")},
},
"bailian": {
Provider: "bailian",
@@ -207,29 +208,6 @@ func providerUnavailableMessages(getenv postgres.Getenv) map[string]string {
return missing
}
func validateProductionProviderConfiguration(getenv postgres.Getenv) error {
if allowUnconfiguredProviders(getenv) {
return nil
}
missing := make([]string, 0, 4)
if strings.TrimSpace(getenv("VOLCENGINE_ACCESS_KEY_ID")) == "" || strings.TrimSpace(getenv("VOLCENGINE_SECRET_ACCESS_KEY")) == "" {
missing = append(missing, "即梦 VOLCENGINE_ACCESS_KEY_ID/VOLCENGINE_SECRET_ACCESS_KEY")
}
if strings.TrimSpace(getenv("EVOLINK_API_KEY")) == "" {
missing = append(missing, "EvoLink EVOLINK_API_KEY")
}
if bailianAPIKey(getenv) == "" {
missing = append(missing, "百炼 BAILIAN_API_KEY/DASHSCOPE_API_KEY")
}
if strings.TrimSpace(getenv("SEEDANCE_API_KEY")) == "" {
missing = append(missing, "Seedance SEEDANCE_API_KEY")
}
if len(missing) == 0 {
return nil
}
return fmt.Errorf("生产环境缺少真实服务商凭据:%s", strings.Join(missing, ";"))
}
func defaultWebhookSender(getenv postgres.Getenv) (*webhook.HTTPSender, error) {
return webhook.NewPublicHTTPSender(
durationEnv(getenv, "ZHINIAN_WEBHOOK_TIMEOUT_MS", 10*time.Second),
@@ -272,6 +250,8 @@ func bailianVideoCapabilityLimits() map[string]any {
func runtimeHealthDetails(getenv postgres.Getenv) httpapi.HealthDetails {
image := imageEngine(getenv)
imageLabel := map[string]string{"jimeng": "即梦", "evolink": "EvoLink", "bailian": "阿里云百炼"}[image]
video := videoEngine(getenv)
videoLabel := map[string]string{"seedance": "Seedance", "bailian": "阿里云百炼"}[video]
visualConfigured := strings.TrimSpace(getenv("VOLCENGINE_ACCESS_KEY_ID")) != "" && strings.TrimSpace(getenv("VOLCENGINE_SECRET_ACCESS_KEY")) != ""
auth, _ := ParseAuthConfig(getenv)
bailianKey := bailianAPIKey(getenv)
@@ -290,7 +270,7 @@ func runtimeHealthDetails(getenv postgres.Getenv) httpapi.HealthDetails {
AuthMode: authMode,
Capabilities: []any{
map[string]any{"id": "image.generate", "label": "图片生成 4.6", "engine": image, "engineLabel": imageLabel, "reqKey": imageModel(getenv)},
map[string]any{"id": "video.generate", "label": "Seedance 视频生成", "engine": "seedance", "engineLabel": "Seedance", "reqKey": firstNonEmpty(getenv("SEEDANCE_MODEL"), "doubao-seedance-2-0-260128")},
map[string]any{"id": "video.generate", "label": "视频生成", "engine": video, "engineLabel": videoLabel, "reqKey": videoModel(getenv)},
},
}
}
@@ -330,6 +310,103 @@ func defaultSettingsService(getenv postgres.Getenv) *settings.Service {
return settings.New(path, runtimeEnvironment(getenv), nil)
}
func databaseSettingsService(getenv postgres.Getenv, repository settings.RuntimeSettingsRepository) *settings.Service {
path := firstNonEmpty(getenv("ZHINIAN_SETTINGS_FILE"), ".env.local")
return settings.NewWithRuntimeRepository(path, runtimeEnvironment(getenv), repository, nil)
}
func runtimeSettingsGetenv(ctx context.Context, fallback postgres.Getenv, service *settings.Service) (postgres.Getenv, error) {
values, err := service.RuntimeValues(ctx)
if err != nil {
return nil, err
}
return mergedSettingsGetenv(values, fallback), nil
}
func cachedRuntimeSettingsGetenv(fallback postgres.Getenv, service *settings.Service) postgres.Getenv {
return mergedSettingsGetenv(service.CachedRuntimeValues(), fallback)
}
func mergedSettingsGetenv(values map[string]string, fallback postgres.Getenv) postgres.Getenv {
return func(name string) string {
if value, ok := values[name]; ok {
return value
}
return fallback(name)
}
}
type runtimeProviderResolver struct {
fallback postgres.Getenv
settings *settings.Service
client *http.Client
maximum int64
}
func newRuntimeProviderResolver(fallback postgres.Getenv, service *settings.Service) *runtimeProviderResolver {
return &runtimeProviderResolver{
fallback: fallback, settings: service,
client: &http.Client{Timeout: durationEnv(fallback, "ZHINIAN_PROVIDER_TIMEOUT_MS", 30*time.Second)},
maximum: positiveInt64Env(fallback, "ZHINIAN_PROVIDER_MAX_RESPONSE_BYTES", 2<<20),
}
}
func (resolver *runtimeProviderResolver) Resolve(ctx context.Context, name string) (providers.Adapter, error) {
getenv, err := runtimeSettingsGetenv(ctx, resolver.fallback, resolver.settings)
if err != nil {
return nil, err
}
return buildProviderRegistryWithClient(getenv, resolver.client, resolver.maximum)[name], nil
}
type runtimeProviderJobBuilder struct {
fallback postgres.Getenv
settings *settings.Service
enforceAvailability bool
}
func (builder runtimeProviderJobBuilder) Build(ctx context.Context, owner, client, capability, idempotency string, body map[string]any) (jobs.CreateCommand, error) {
getenv, err := runtimeSettingsGetenv(ctx, builder.fallback, builder.settings)
if err != nil {
return jobs.CreateCommand{}, fmt.Errorf("load runtime provider settings: %w", err)
}
return configuredProviderJobBuilder(getenv, builder.enforceAvailability).Build(ctx, owner, client, capability, idempotency, body)
}
func configuredProviderJobBuilder(getenv postgres.Getenv, enforceAvailability bool) jobs.ProviderJobBuilder {
var unavailable map[string]string
if enforceAvailability {
unavailable = providerUnavailableMessages(getenv)
}
return jobs.ProviderJobBuilder{
ImageProvider: imageProvider(getenv), VideoProvider: videoProvider(getenv),
ImageModel: imageModel(getenv), VideoModel: videoModel(getenv), ImageEngine: imageEngine(getenv), VideoEngine: videoEngine(getenv),
ImageEngines: providerImageTargets(getenv), VideoEngines: providerVideoTargets(getenv), UnavailableProviders: unavailable, NewID: applicationJobID,
}
}
func runtimeCapabilitySummary(fallback postgres.Getenv, service *settings.Service) func(context.Context) (any, error) {
return func(ctx context.Context) (any, error) {
getenv, err := runtimeSettingsGetenv(ctx, fallback, service)
if err != nil {
return nil, fmt.Errorf("load runtime provider settings: %w", err)
}
return capabilitySummary(getenv)(ctx)
}
}
func runtimeHealthDetailsProvider(fallback postgres.Getenv, service *settings.Service) func(context.Context) httpapi.HealthDetails {
return func(ctx context.Context) httpapi.HealthDetails {
refreshContext, cancel := context.WithTimeout(ctx, 250*time.Millisecond)
defer cancel()
getenv, err := runtimeSettingsGetenv(refreshContext, fallback, service)
if err != nil {
getenv = cachedRuntimeSettingsGetenv(fallback, service)
}
return runtimeHealthDetails(getenv)
}
}
type settingsBillingAccountStore struct{ service *settings.Service }
func (store settingsBillingAccountStore) Load(ctx context.Context) (billing.AccountConfig, error) {