auto-save 2026-05-26 10:00 (~2)
This commit is contained in:
@@ -1,43 +1,5 @@
|
|||||||
{
|
{
|
||||||
"entries": [
|
"entries": [
|
||||||
{
|
|
||||||
"files_changed": 3,
|
|
||||||
"hash": "d6bba9d",
|
|
||||||
"message": "auto-save 2026-05-20 14:45 (~3)",
|
|
||||||
"ts": "2026-05-20T14:45:09+08:00",
|
|
||||||
"type": "commit"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"files_changed": 1,
|
|
||||||
"message": "Codex 会话活跃 · 最近命令:codex · 分支 main · 1 项未提交变更 · 最近提交:auto-save 2026-05-20 14:45 (~3)",
|
|
||||||
"ts": "2026-05-20T06:53:59Z",
|
|
||||||
"type": "session-heartbeat"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"files_changed": 2,
|
|
||||||
"message": "启动 Claude 接力会话 · 已载入 Claude / Codex 最近会话,等待下一条指令 · 分支 main · 2 项未提交变更 · 最近提交:auto-save 2026-05-20 14:45 (~3)",
|
|
||||||
"ts": "2026-05-20T06:57:19Z",
|
|
||||||
"type": "assistant-session"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"files_changed": 2,
|
|
||||||
"hash": "1e995c3",
|
|
||||||
"message": "auto-save 2026-05-20 15:01 (~2)",
|
|
||||||
"ts": "2026-05-20T15:01:24+08:00",
|
|
||||||
"type": "commit"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"files_changed": 1,
|
|
||||||
"message": "Codex 会话活跃 · 最近命令:codex · 分支 main · 1 项未提交变更 · 最近提交:auto-save 2026-05-20 15:01 (~2)",
|
|
||||||
"ts": "2026-05-20T07:03:59Z",
|
|
||||||
"type": "session-heartbeat"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"files_changed": 1,
|
|
||||||
"message": "Claude 会话活跃 · 最近命令:claude · 分支 main · 1 项未提交变更 · 最近提交:auto-save 2026-05-20 15:01 (~2)",
|
|
||||||
"ts": "2026-05-20T07:07:21Z",
|
|
||||||
"type": "session-heartbeat"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"files_changed": 2,
|
"files_changed": 2,
|
||||||
"message": "Claude 会话结束 · 持续 0 秒 · 最近命令:claude · 分支 main · 2 项未提交变更 · 最近提交:auto-save 2026-05-20 15:01 (~2)",
|
"message": "Claude 会话结束 · 持续 0 秒 · 最近命令:claude · 分支 main · 2 项未提交变更 · 最近提交:auto-save 2026-05-20 15:01 (~2)",
|
||||||
@@ -3206,6 +3168,45 @@
|
|||||||
"type": "session-heartbeat",
|
"type": "session-heartbeat",
|
||||||
"message": "Codex 会话活跃 · 最近命令:codex · 分支 main · 1 项未提交变更 · 最近提交:chore: migrate legacy password data to Feishu owner",
|
"message": "Codex 会话活跃 · 最近命令:codex · 分支 main · 1 项未提交变更 · 最近提交:chore: migrate legacy password data to Feishu owner",
|
||||||
"files_changed": 1
|
"files_changed": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-26T09:39:00+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-26 09:38 (~2)",
|
||||||
|
"hash": "836a33e",
|
||||||
|
"files_changed": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-26T01:39:34Z",
|
||||||
|
"type": "session-heartbeat",
|
||||||
|
"message": "Codex 会话活跃 · 最近命令:codex · 分支 main · 2 项未提交变更 · 最近提交:auto-save 2026-05-26 09:38 (~2)",
|
||||||
|
"files_changed": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-26T09:41:03+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "fix: explain video generation failures",
|
||||||
|
"hash": "579e538",
|
||||||
|
"files_changed": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-26T09:43:02+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "docs: record video error deployment",
|
||||||
|
"hash": "591bc37",
|
||||||
|
"files_changed": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-26T01:49:34Z",
|
||||||
|
"type": "session-heartbeat",
|
||||||
|
"message": "Codex 会话活跃 · 最近命令:codex · 分支 main · 1 项未提交变更 · 最近提交:docs: record video error deployment",
|
||||||
|
"files_changed": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-26T01:59:34Z",
|
||||||
|
"type": "session-heartbeat",
|
||||||
|
"message": "Codex 会话活跃 · 最近命令:codex · 分支 main · 2 项未提交变更 · 最近提交:docs: record video error deployment",
|
||||||
|
"files_changed": 2
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
87
api/main.py
87
api/main.py
@@ -5268,6 +5268,18 @@ class CreativeCopyResp(BaseModel):
|
|||||||
variants: list[CreativeCopyVariant]
|
variants: list[CreativeCopyVariant]
|
||||||
|
|
||||||
|
|
||||||
|
class PromptPolishReq(BaseModel):
|
||||||
|
text: str
|
||||||
|
system_prompt: str = ""
|
||||||
|
mode: Literal["image", "video", "general"] = "image"
|
||||||
|
target_language: Literal["en", "zh", "keep"] = "en"
|
||||||
|
|
||||||
|
|
||||||
|
class PromptPolishResp(BaseModel):
|
||||||
|
model: str
|
||||||
|
text: str
|
||||||
|
|
||||||
|
|
||||||
class ScriptRewriteSegmentReq(BaseModel):
|
class ScriptRewriteSegmentReq(BaseModel):
|
||||||
index: int
|
index: int
|
||||||
start: float = 0.0
|
start: float = 0.0
|
||||||
@@ -5400,6 +5412,81 @@ def _parse_creative_copy_response(raw: str, req: CreativeCopyReq) -> CreativeCop
|
|||||||
return CreativeCopyResp(model=REWRITE_MODEL if LLM_API_KEY else "fallback", variants=variants)
|
return CreativeCopyResp(model=REWRITE_MODEL if LLM_API_KEY else "fallback", variants=variants)
|
||||||
|
|
||||||
|
|
||||||
|
def _prompt_polish_fallback(req: PromptPolishReq) -> PromptPolishResp:
|
||||||
|
text = req.text.strip()
|
||||||
|
base = _ensure_english(text) if req.target_language == "en" else text
|
||||||
|
base = re.sub(r"\s+", " ", base).strip()
|
||||||
|
if req.mode == "video":
|
||||||
|
polished = (
|
||||||
|
f"{base}. Smooth camera movement, clear subject continuity, stable composition, "
|
||||||
|
"natural motion, coherent lighting, no subtitles, no watermark."
|
||||||
|
)
|
||||||
|
elif req.mode == "general":
|
||||||
|
polished = base
|
||||||
|
else:
|
||||||
|
polished = (
|
||||||
|
f"{base}. Detailed visual prompt, clear main subject, coherent composition, "
|
||||||
|
"natural lighting, refined color palette, high-quality details."
|
||||||
|
)
|
||||||
|
return PromptPolishResp(model="fallback", text=polished[:1800])
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/prompt/polish", response_model=PromptPolishResp)
|
||||||
|
def polish_prompt(req: PromptPolishReq) -> PromptPolishResp:
|
||||||
|
text = req.text.strip()
|
||||||
|
if not text:
|
||||||
|
raise HTTPException(400, "text required")
|
||||||
|
if not LLM_API_KEY:
|
||||||
|
return _prompt_polish_fallback(req)
|
||||||
|
|
||||||
|
target_label = {
|
||||||
|
"en": "English",
|
||||||
|
"zh": "Simplified Chinese",
|
||||||
|
"keep": "the same language as the input",
|
||||||
|
}.get(req.target_language, "English")
|
||||||
|
mode_hint = {
|
||||||
|
"image": "an image-generation prompt",
|
||||||
|
"video": "a video-generation prompt",
|
||||||
|
"general": "a concise generation prompt",
|
||||||
|
}.get(req.mode, "an image-generation prompt")
|
||||||
|
user_system = req.system_prompt.strip()
|
||||||
|
prompt = (
|
||||||
|
f"Rewrite the user's input into {mode_hint} in {target_label}.\n"
|
||||||
|
"Preserve the user's actual subject, brand, product, place, style, and intent.\n"
|
||||||
|
"Do not add SKG, health-tech, massage products, TikTok ad framing, product sales language, hashtags, captions, or any brand/product not explicitly present in the input.\n"
|
||||||
|
"Do not add medical, wellness, or advertising claims unless the user asked for them.\n"
|
||||||
|
"Improve concrete visual details, composition, lighting, camera language, materials, mood, and quality.\n"
|
||||||
|
"Return only the rewritten prompt. No markdown, labels, JSON, quotes, explanation, or alternatives.\n"
|
||||||
|
)
|
||||||
|
if req.mode == "video":
|
||||||
|
prompt += (
|
||||||
|
"For video, describe motion, timing, camera movement, continuity, and what changes over time. "
|
||||||
|
"If people are not essential, prefer no recognizable faces or distant/turned-away background people to reduce video safety risk.\n"
|
||||||
|
)
|
||||||
|
if user_system:
|
||||||
|
prompt += f"\nUser-selected polishing guidance:\n{user_system[:1000]}\n"
|
||||||
|
prompt += f"\nInput:\n{text[:2500]}"
|
||||||
|
|
||||||
|
try:
|
||||||
|
resp = llm().chat.completions.create(
|
||||||
|
model=REWRITE_MODEL,
|
||||||
|
messages=[
|
||||||
|
{"role": "system", "content": "You are a neutral professional prompt editor. You preserve intent and never inject unrelated brands or products."},
|
||||||
|
{"role": "user", "content": prompt},
|
||||||
|
],
|
||||||
|
temperature=0.45,
|
||||||
|
max_tokens=900,
|
||||||
|
)
|
||||||
|
out = (resp.choices[0].message.content or "").strip()
|
||||||
|
out = re.sub(r"^```(?:text)?\s*", "", out, flags=re.I).strip()
|
||||||
|
out = re.sub(r"\s*```$", "", out).strip()
|
||||||
|
out = re.sub(r'^[\'"「『]+|[\'"」』]+$', "", out).strip()
|
||||||
|
return PromptPolishResp(model=REWRITE_MODEL, text=(out or _prompt_polish_fallback(req).text)[:1800])
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[prompt polish fallback] {e}", flush=True)
|
||||||
|
return _prompt_polish_fallback(req)
|
||||||
|
|
||||||
|
|
||||||
@app.post("/translate")
|
@app.post("/translate")
|
||||||
def translate_text(req: TranslateReq) -> dict:
|
def translate_text(req: TranslateReq) -> dict:
|
||||||
"""单条文本翻译(给生图自定义提取元素 zh→en 用)"""
|
"""单条文本翻译(给生图自定义提取元素 zh→en 用)"""
|
||||||
|
|||||||
Reference in New Issue
Block a user