Update
This commit is contained in:
@@ -172,6 +172,38 @@ class GatewayService(BaseService):
|
||||
help="The key currently in use; falls back to the vision/OPENROUTER key on boot (embeddings default to OpenRouter). Editable.",
|
||||
group="Embeddings",
|
||||
),
|
||||
ConfigField(
|
||||
"gateway_image_enabled",
|
||||
"Image generation",
|
||||
type="bool",
|
||||
default=True,
|
||||
help="Expose image generation at /openai/v1/images/generations.",
|
||||
group="Images",
|
||||
),
|
||||
ConfigField(
|
||||
"gateway_image_url",
|
||||
"Images URL",
|
||||
type="url",
|
||||
default=config.IMAGE_URL_DEFAULT,
|
||||
help="OpenAI-compatible images/generations endpoint requests are forwarded to.",
|
||||
group="Images",
|
||||
),
|
||||
ConfigField(
|
||||
"gateway_image_model",
|
||||
"Images model",
|
||||
type="str",
|
||||
default=config.IMAGE_MODEL_DEFAULT,
|
||||
help="Image model sent upstream. Clients request it as molodetz-img-small.",
|
||||
group="Images",
|
||||
),
|
||||
ConfigField(
|
||||
"gateway_image_key",
|
||||
"Images API key",
|
||||
type="str",
|
||||
default="",
|
||||
help="The key currently in use; falls back to gateway_api_key / OPENROUTER_API_KEY on boot. Editable.",
|
||||
group="Images",
|
||||
),
|
||||
ConfigField(
|
||||
"gateway_require_auth",
|
||||
"Require authentication",
|
||||
@@ -267,6 +299,15 @@ class GatewayService(BaseService):
|
||||
help="Fallback only; used when the embeddings upstream returns no native cost.",
|
||||
group="Pricing",
|
||||
),
|
||||
ConfigField(
|
||||
"gateway_image_price_per_call",
|
||||
"Images price / call ($)",
|
||||
type="float",
|
||||
default=config.IMAGE_PRICE_PER_CALL_DEFAULT,
|
||||
minimum=0,
|
||||
help="Fallback only; used when the image upstream returns no native cost.",
|
||||
group="Pricing",
|
||||
),
|
||||
ConfigField(
|
||||
"gateway_rsearch_cost_per_call",
|
||||
"rsearch cost / call ($)",
|
||||
@@ -355,6 +396,17 @@ class GatewayService(BaseService):
|
||||
or cfg["gateway_vision_key"]
|
||||
or os.environ.get("OPENROUTER_API_KEY", "")
|
||||
)
|
||||
cfg["gateway_image_key"] = (
|
||||
cfg["gateway_image_key"]
|
||||
or cfg["gateway_api_key"]
|
||||
or os.environ.get("OPENROUTER_API_KEY", "")
|
||||
)
|
||||
if not cfg.get("gateway_image_url"):
|
||||
upstream = cfg.get("gateway_upstream_url", "")
|
||||
if upstream.endswith("/chat/completions"):
|
||||
cfg["gateway_image_url"] = (
|
||||
upstream[: -len("/chat/completions")] + "/images"
|
||||
)
|
||||
return cfg
|
||||
|
||||
def authorize(self, request: Request) -> bool:
|
||||
@@ -429,6 +481,18 @@ class GatewayService(BaseService):
|
||||
return await runtime.handle_embeddings(
|
||||
body, cfg, owner, user_agent, self.log
|
||||
)
|
||||
if subpath == "images/generations" and request.method == "POST":
|
||||
try:
|
||||
body = await request.json()
|
||||
except Exception:
|
||||
self.log("Rejected images request: invalid JSON body")
|
||||
raise HTTPException(status_code=400, detail="Invalid JSON body")
|
||||
if not isinstance(body, dict):
|
||||
self.log("Rejected images request: JSON body was not an object")
|
||||
raise HTTPException(status_code=400, detail="Invalid JSON body")
|
||||
return await runtime.handle_images(
|
||||
body, cfg, owner, user_agent, self.log
|
||||
)
|
||||
body = await request.body()
|
||||
content_type = request.headers.get("content-type", "")
|
||||
return await runtime.handle_passthrough(
|
||||
@@ -473,6 +537,7 @@ class GatewayService(BaseService):
|
||||
"peak_in_flight": 0,
|
||||
"vision_calls": 0,
|
||||
"embed_calls": 0,
|
||||
"image_calls": 0,
|
||||
"last_status": 0,
|
||||
"last_latency_ms": 0,
|
||||
"pool": 0,
|
||||
@@ -485,12 +550,14 @@ class GatewayService(BaseService):
|
||||
{"label": "In flight", "value": m["in_flight"]},
|
||||
{"label": "Vision calls", "value": m["vision_calls"]},
|
||||
{"label": "Embed calls", "value": m["embed_calls"]},
|
||||
{"label": "Image calls", "value": m["image_calls"]},
|
||||
{"label": "Last status", "value": m["last_status"] or "-"},
|
||||
{"label": "Last latency", "value": f"{m['last_latency_ms']} ms"},
|
||||
{"label": "Pool size", "value": m["pool"]},
|
||||
{"label": "Circuit", "value": "open" if m["circuit_open"] else "closed"},
|
||||
{"label": "Model", "value": cfg["gateway_model"]},
|
||||
{"label": "Embed model", "value": cfg["gateway_embed_model"]},
|
||||
{"label": "Image model", "value": cfg["gateway_image_model"]},
|
||||
{"label": "Requests 24h", "value": s["requests"]},
|
||||
{"label": "Success 24h", "value": f"{s['success_pct']}%"},
|
||||
{"label": "Error rate 24h", "value": f"{s['error_pct']}%"},
|
||||
|
||||
Reference in New Issue
Block a user