Download services/image_model_service.py from zlcy/study: direct link, hf CLI and curl.
- Browser
- Download file 3.59 kB
-
https://huggingface.co/spaces/zlcy/study/resolve/main/services/image_model_service.py
- Command line
-
hf download hf://spaces/zlcy/study/services/image_model_service.py
-
curl -L -o image_model_service.py https://huggingface.co/spaces/zlcy/study/resolve/main/services/image_model_service.py
3.59 kB
| """生图可用模型的判定规则(与「对话可用模型」对称)。 | |
| ``/api/image/models`` 给出**全部能生图的模型**:账号池上游内置生图模型 | |
| (``gpt-image-2`` 及其 codex 变体)+ 第三方接入的生图模型。 | |
| 候选判据复用 services/chat_model_service.py 的 ``supports_image_generation``: | |
| 优先看第三方的能力字段(``txt2img`` / ``img2img``),没有该字段的上游模型退回名字判定。 | |
| 多模态模型(能力里同时有 ``chat`` 与 ``txt2img``)会同时出现在对话与生图两个列表里。 | |
| **默认全部启用。** 第三方生图模型能不能用,本来就由第三方生图配置(分组 / 模型开关、 | |
| 计费、路由)决定;这里的开关只是**展示层过滤**,只影响模型是否出现在生图下拉里, | |
| 不改变计费、路由、额度与对外 API 的行为。所以升级后不会莫名其妙少模型, | |
| 管理员可以按需勾掉不想在列表里看到的。 | |
| """ | |
| from __future__ import annotations | |
| from typing import Any | |
| from services.chat_model_service import ( | |
| SOURCE_THIRD_PARTY, | |
| SOURCE_UPSTREAM, | |
| _clean, | |
| image_capabilities, | |
| model_source, | |
| supports_image_generation, | |
| ) | |
| # 生图列表里的来源标签:上游内置生图模型 / 第三方接入生图模型。 | |
| IMAGE_SOURCE_BUILTIN = "builtin" | |
| IMAGE_SOURCE_THIRD_PARTY = "third_party" | |
| def image_model_source(item: dict[str, Any]) -> str: | |
| """生图模型的来源:``builtin`` = 账号池上游内置,``third_party`` = 第三方接入。""" | |
| if model_source(item) == SOURCE_THIRD_PARTY: | |
| return IMAGE_SOURCE_THIRD_PARTY | |
| return IMAGE_SOURCE_BUILTIN | |
| def _clean_id_set(value: object) -> set[str]: | |
| if not isinstance(value, list): | |
| return set() | |
| return {_clean(item) for item in value if _clean(item)} | |
| def resolve_image_models( | |
| items: list[Any], | |
| overrides: dict[str, Any] | None = None, | |
| ) -> list[dict[str, Any]]: | |
| """筛出能生图的模型,并标注 ``image_enabled`` / ``image_default_enabled``。 | |
| 只保留 ``supports_image_generation`` 为真的条目(对话模型不会混进来); | |
| 分不清能不能生图的模型一律不放进候选,避免生图下拉里出现选不了的模型。 | |
| """ | |
| source = overrides if isinstance(overrides, dict) else {} | |
| include = _clean_id_set(source.get("include")) | |
| exclude = _clean_id_set(source.get("exclude")) | |
| resolved: list[dict[str, Any]] = [] | |
| for item in items or []: | |
| if not isinstance(item, dict): | |
| continue | |
| model_id = _clean(item.get("id")) | |
| if not model_id or not supports_image_generation(item): | |
| continue | |
| if model_id in include: | |
| enabled = True | |
| elif model_id in exclude: | |
| enabled = False | |
| else: | |
| enabled = True | |
| resolved.append({ | |
| **item, | |
| "image_enabled": enabled, | |
| "image_default_enabled": True, | |
| "image_source": image_model_source(item), | |
| "image_capabilities": sorted(image_capabilities(item)), | |
| }) | |
| # 已启用的排前面;同组内上游内置模型优先,再按模型名排序。 | |
| resolved.sort(key=lambda entry: ( | |
| 0 if entry["image_enabled"] else 1, | |
| 0 if entry["image_source"] == IMAGE_SOURCE_BUILTIN else 1, | |
| str(entry.get("id") or ""), | |
| )) | |
| return resolved | |
| __all__ = [ | |
| "IMAGE_SOURCE_BUILTIN", | |
| "IMAGE_SOURCE_THIRD_PARTY", | |
| "image_model_source", | |
| "resolve_image_models", | |
| "SOURCE_THIRD_PARTY", | |
| "SOURCE_UPSTREAM", | |
| ] | |