auto-save 2026-05-27 17:13 (~2)

This commit is contained in:
2026-05-27 17:13:16 +08:00
parent ec38215dd5
commit 8999fe0baf
2 changed files with 123 additions and 36 deletions

View File

@@ -109,6 +109,10 @@ REWRITE_MODEL = gpt_model_env("REWRITE_MODEL")
VISION_MODEL = gpt_model_env("VISION_MODEL")
IMAGE_BASE_URL = os.getenv("IMAGE_BASE_URL", LLM_BASE_URL).strip()
IMAGE_API_KEY = os.getenv("IMAGE_API_KEY", LLM_API_KEY).strip()
ARK_IMAGE_BASE_URL = os.getenv("ARK_IMAGE_BASE_URL", "https://ark.cn-beijing.volces.com/api/v3").strip()
ARK_IMAGE_API_KEY = (os.getenv("ARK_IMAGE_API_KEY") or os.getenv("SEEDREAM_API_KEY") or "").strip()
ARK_SEEDREAM_IMAGE_MODEL = os.getenv("ARK_SEEDREAM_IMAGE_MODEL", "doubao-seedream-4-5-251128").strip() or "doubao-seedream-4-5-251128"
ARK_SEEDREAM_ENABLED = os.getenv("ARK_SEEDREAM_ENABLED", "true").strip().lower() not in {"0", "false", "no", "off"}
AI_HTTP_PROXY = (
os.getenv("AI_HTTP_PROXY")
or os.getenv("IMAGE_HTTP_PROXY")
@@ -118,15 +122,43 @@ AI_HTTP_PROXY = (
or os.getenv("http_proxy")
or ""
).strip()
# Product decision: gpt-image-2 remains the primary image model. Gemini is only
# allowed as an outage fallback when the primary gateway times out or returns
# transient upstream failures.
GPT_IMAGE_MODEL = "gpt-image-2"
DEFAULT_GPT_IMAGE_MODEL = "gpt-image-2"
GPT_IMAGE_MODEL = os.getenv("GPT_IMAGE_MODEL", DEFAULT_GPT_IMAGE_MODEL).strip() or DEFAULT_GPT_IMAGE_MODEL
IMAGE_MODEL = os.getenv("IMAGE_MODEL", GPT_IMAGE_MODEL).strip() or GPT_IMAGE_MODEL
IMAGE_FALLBACK_MODEL = os.getenv("IMAGE_FALLBACK_MODEL", "gemini-3-pro-image-preview").strip() or ""
IMAGE_FALLBACK_ENABLED = os.getenv("IMAGE_FALLBACK_ENABLED", "true").strip().lower() not in {"0", "false", "no", "off"}
IMAGE_MODEL = GPT_IMAGE_MODEL
PRODUCT_VIEW_MODEL = GPT_IMAGE_MODEL
SUBJECT_ASSET_IMAGE_MODEL = GPT_IMAGE_MODEL
IMAGE_FALLBACK_MODELS = [
item.strip()
for item in os.getenv("IMAGE_FALLBACK_MODELS", IMAGE_FALLBACK_MODEL).split(",")
if item.strip()
]
IMAGE_EXTRA_MODELS = [
item.strip()
for item in os.getenv("IMAGE_EXTRA_MODELS", "").split(",")
if item.strip()
]
PRODUCT_VIEW_MODEL = os.getenv("PRODUCT_VIEW_MODEL", GPT_IMAGE_MODEL).strip() or GPT_IMAGE_MODEL
SUBJECT_ASSET_IMAGE_MODEL = os.getenv("SUBJECT_ASSET_IMAGE_MODEL", IMAGE_MODEL).strip() or IMAGE_MODEL
IMAGE_MODEL_CONFIGS_JSON = os.getenv("IMAGE_MODEL_CONFIGS_JSON", "").strip()
try:
_IMAGE_MODEL_CONFIG_OVERRIDES_RAW = json.loads(IMAGE_MODEL_CONFIGS_JSON) if IMAGE_MODEL_CONFIGS_JSON else {}
if isinstance(_IMAGE_MODEL_CONFIG_OVERRIDES_RAW, list):
IMAGE_MODEL_CONFIG_OVERRIDES = {
str(item.get("id") or item.get("model")).strip(): item
for item in _IMAGE_MODEL_CONFIG_OVERRIDES_RAW
if isinstance(item, dict) and (item.get("id") or item.get("model"))
}
elif isinstance(_IMAGE_MODEL_CONFIG_OVERRIDES_RAW, dict):
IMAGE_MODEL_CONFIG_OVERRIDES = {
str(key).strip(): value
for key, value in _IMAGE_MODEL_CONFIG_OVERRIDES_RAW.items()
if str(key).strip() and isinstance(value, dict)
}
else:
IMAGE_MODEL_CONFIG_OVERRIDES = {}
except Exception as e:
print(f"[image config] invalid IMAGE_MODEL_CONFIGS_JSON ignored: {e}", flush=True)
IMAGE_MODEL_CONFIG_OVERRIDES = {}
IMAGE_SIZE_CHOICES = [
{
"id": "auto",
@@ -153,6 +185,54 @@ IMAGE_SIZE_CHOICES = [
"description": "适合横版封面和详情页配图",
},
]
ARK_SEEDREAM_SIZE_CHOICES = [
{
"id": "2K",
"label": "自动 2K",
"value": "2K",
"description": "Seedream 自行决定接近 2K 的输出尺寸",
},
{
"id": "2048x2048",
"label": "方图 2048",
"value": "2048x2048",
"description": "Seedream 方图,满足 4.5 最低像素要求",
},
{
"id": "1440x2560",
"label": "竖图 9:16",
"value": "1440x2560",
"description": "Seedream 竖版营销图",
},
{
"id": "2560x1440",
"label": "横图 16:9",
"value": "2560x1440",
"description": "Seedream 横版封面或网页图",
},
{
"id": "2160x2160",
"label": "方图 2160",
"value": "2160x2160",
"description": "Seedream 高清方图",
},
{
"id": "2160x3840",
"label": "竖图 4K",
"value": "2160x3840",
"description": "Seedream 竖版高分辨率输出",
},
{
"id": "3840x2160",
"label": "横图 4K",
"value": "3840x2160",
"description": "Seedream 横版高分辨率输出",
},
]
ALL_IMAGE_SIZE_CHOICES = IMAGE_SIZE_CHOICES + [
item for item in ARK_SEEDREAM_SIZE_CHOICES
if item["value"] not in {base["value"] for base in IMAGE_SIZE_CHOICES}
]
VIDEO_SIZE_CHOICES = [
{
"id": "720x1280",
@@ -183,9 +263,14 @@ SubjectModelBundle = Literal["gpt", "gemini"]
SubjectAgentMode = Literal["realistic", "cartoon", "elements", "custom"]
SUBJECT_AGENT_GPT_MODEL = gpt_model_env("SUBJECT_AGENT_GPT_MODEL", VISION_MODEL)
SUBJECT_AGENT_GEMINI_MODEL = os.getenv("SUBJECT_AGENT_GEMINI_MODEL", "gemini-2.5-flash").strip() or "gemini-2.5-flash"
SUBJECT_ASSET_IMAGE_MODELS = [GPT_IMAGE_MODEL] + (
[IMAGE_FALLBACK_MODEL] if IMAGE_FALLBACK_ENABLED and IMAGE_FALLBACK_MODEL and IMAGE_FALLBACK_MODEL != GPT_IMAGE_MODEL else []
)
SUBJECT_ASSET_IMAGE_MODELS = [
item.strip()
for item in os.getenv(
"SUBJECT_ASSET_IMAGE_MODELS",
",".join([SUBJECT_ASSET_IMAGE_MODEL, *IMAGE_FALLBACK_MODELS]),
).split(",")
if item.strip()
]
IMAGE_REQUEST_TIMEOUT_SECONDS = max(15, min(180, int(os.getenv("IMAGE_REQUEST_TIMEOUT_SECONDS", "60"))))
IMAGE_CIRCUIT_FAILURE_THRESHOLD = max(1, int(os.getenv("IMAGE_CIRCUIT_FAILURE_THRESHOLD", "2")))
IMAGE_CIRCUIT_COOLDOWN_SECONDS = max(60, int(os.getenv("IMAGE_CIRCUIT_COOLDOWN_SECONDS", "600")))