fix: route ai polish through available models
This commit is contained in:
64
api/main.py
64
api/main.py
@@ -107,6 +107,11 @@ def gpt_model_env(name: str, default: str | None = None) -> str:
|
||||
|
||||
|
||||
REWRITE_MODEL = gpt_model_env("REWRITE_MODEL")
|
||||
REWRITE_MODEL_FALLBACKS = [
|
||||
model.strip()
|
||||
for model in os.getenv("REWRITE_MODEL_FALLBACKS", "gpt-4o-mini,gemini-2.5-flash").split(",")
|
||||
if model.strip()
|
||||
]
|
||||
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()
|
||||
@@ -5914,6 +5919,7 @@ class CreativeCopyResp(BaseModel):
|
||||
class PromptPolishReq(BaseModel):
|
||||
text: str
|
||||
system_prompt: str = ""
|
||||
model: str = ""
|
||||
mode: Literal["image", "video", "general", "chat"] = "image"
|
||||
target_language: Literal["en", "zh", "keep"] = "en"
|
||||
|
||||
@@ -6320,11 +6326,26 @@ def _prompt_polish_fallback(req: PromptPolishReq) -> PromptPolishResp:
|
||||
return PromptPolishResp(model="fallback", text=_sanitize_polished_prompt(req, intent, _basic_polished_prompt(req, intent)))
|
||||
|
||||
|
||||
def _repair_polished_prompt(req: PromptPolishReq, intent: PromptIntent, output: str, *, allow_llm: bool = False) -> str:
|
||||
def _prompt_polish_model_candidates(req: PromptPolishReq) -> list[str]:
|
||||
requested = (req.model or "").strip()
|
||||
candidates = [requested, REWRITE_MODEL, *REWRITE_MODEL_FALLBACKS]
|
||||
seen: set[str] = set()
|
||||
out: list[str] = []
|
||||
for model in candidates:
|
||||
model = model.strip()
|
||||
key = model.lower()
|
||||
if model and key not in seen:
|
||||
out.append(model)
|
||||
seen.add(key)
|
||||
return out
|
||||
|
||||
|
||||
def _repair_polished_prompt(req: PromptPolishReq, intent: PromptIntent, output: str, *, allow_llm: bool = False, model: str | None = None) -> str:
|
||||
out = _sanitize_polished_prompt(req, intent, output)
|
||||
issue = _polished_prompt_issue(intent, out)
|
||||
if not issue or not allow_llm or not LLM_API_KEY:
|
||||
return out
|
||||
repair_model = (model or REWRITE_MODEL).strip() or REWRITE_MODEL
|
||||
repair_prompt = (
|
||||
"Repair the rewritten generation prompt so it follows the source input exactly.\n"
|
||||
f"Issue to fix: {issue}.\n"
|
||||
@@ -6340,7 +6361,7 @@ def _repair_polished_prompt(req: PromptPolishReq, intent: PromptIntent, output:
|
||||
)
|
||||
try:
|
||||
resp = llm().chat.completions.create(
|
||||
model=REWRITE_MODEL,
|
||||
model=repair_model,
|
||||
messages=[
|
||||
{"role": "system", "content": "You repair generation prompts by removing contradictions and preserving only source intent."},
|
||||
{"role": "user", "content": repair_prompt},
|
||||
@@ -6410,23 +6431,28 @@ def polish_prompt(req: PromptPolishReq) -> PromptPolishResp:
|
||||
prompt += f"\nUser-selected polishing guidance:\n{user_system[:1000]}\n"
|
||||
prompt += f"\nSource input:\n{intent.cleaned_text[:2500]}"
|
||||
|
||||
try:
|
||||
resp = llm().chat.completions.create(
|
||||
model=REWRITE_MODEL,
|
||||
messages=[
|
||||
{"role": "system", "content": "You are a neutral professional prompt editor. Preserve source intent exactly and never inject SKG or unrelated brands, products, platforms, people, or marketing context."},
|
||||
{"role": "user", "content": prompt},
|
||||
],
|
||||
temperature=0.45,
|
||||
max_tokens=900,
|
||||
)
|
||||
out = _clean_prompt_output(resp.choices[0].message.content or "")
|
||||
if not out:
|
||||
out = _prompt_polish_fallback(req).text
|
||||
return PromptPolishResp(model=REWRITE_MODEL, text=_repair_polished_prompt(req, intent, out, allow_llm=True))
|
||||
except Exception as e:
|
||||
print(f"[prompt polish fallback] {e}", flush=True)
|
||||
return _prompt_polish_fallback(req)
|
||||
model_errors: list[str] = []
|
||||
for model in _prompt_polish_model_candidates(req):
|
||||
try:
|
||||
resp = llm().chat.completions.create(
|
||||
model=model,
|
||||
messages=[
|
||||
{"role": "system", "content": "You are a neutral professional prompt editor. Preserve source intent exactly and never inject SKG or unrelated brands, products, platforms, people, or marketing context."},
|
||||
{"role": "user", "content": prompt},
|
||||
],
|
||||
temperature=0.45,
|
||||
max_tokens=900,
|
||||
)
|
||||
out = _clean_prompt_output(resp.choices[0].message.content or "")
|
||||
if not out:
|
||||
raise RuntimeError("empty prompt polish response")
|
||||
return PromptPolishResp(model=model, text=_repair_polished_prompt(req, intent, out, allow_llm=True, model=model))
|
||||
except Exception as e:
|
||||
message = str(e).replace("\n", " ")[:400]
|
||||
model_errors.append(f"{model}: {message}")
|
||||
print(f"[prompt polish model fallback] model={model} error={message}", flush=True)
|
||||
print(f"[prompt polish fallback] {' | '.join(model_errors)}", flush=True)
|
||||
return _prompt_polish_fallback(req)
|
||||
|
||||
|
||||
@app.post("/translate")
|
||||
|
||||
Reference in New Issue
Block a user