fix(cheap-worker): 真后端 gameId int→str 归一化(治便宜档经真后端全失败的阻断 bug)

A11 受计费真后端 e2e(mini-desktop 隔离实例)抓到的阻断性 seam bug:
后端 gameId 是 Java Long → JSON number → Python int;worker 直传 cheap_run 的
subprocess shell-out(scaffold/build/stage/smoke/play 要求 str)→ TypeError(expected str, not int)
→ scaffold 失败 → 静默归 llm_error → 便宜档经真后端 generate/modify 全部失败。

本机单测用 str gameId 没暴露;真后端 Java int gameId 才触发(e2e 的价值)。
修:_default_run_fn / _process_modify_job / _process_regenerate_job 三处 job 消费边界
归一 game_id=str(...)(str("x")=no-op,既有零影响)。e2e 重跑后全链路成功。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
lili 2026-06-29 04:26:14 -07:00
parent 6998de77f3
commit 0465471ef4

View File

@ -138,6 +138,9 @@ def _default_run_fn(job: dict):
import cheap_studio
game_id = job.get("gameId") or job.get("job_id")
# 真后端来的 gameId 是 Java Long → JSON 数字 → Python intcheap_run 的 subprocess shell-outscaffold/build/stage/smoke/play
# 与路径段都要求 strint 会抛 TypeError(expected str, not int) → 生成静默判 llm_error。此处在 job 消费边界统一归一为 str。
game_id = str(game_id) if game_id is not None else None
brief = job.get("brief") or ""
summary = asyncio.run(cheap_studio.run_studio(game_id, brief))
return summary, cheap_run.game_dir(game_id)
@ -257,6 +260,9 @@ def _process_modify_job(state: WorkerState, job: dict, modify: dict) -> dict:
trace_id = job.get("traceId") or job.get("job_id")
mode = modify.get("mode")
game_id = job.get("gameId") or job.get("job_id")
# 真后端来的 gameId 是 Java Long → JSON 数字 → Python intcheap_run 的 subprocess shell-outscaffold/build/stage/smoke/play
# 与路径段都要求 strint 会抛 TypeError(expected str, not int) → 生成静默判 llm_error。此处在 job 消费边界统一归一为 str。
game_id = str(game_id) if game_id is not None else None
# A11 M4:模块重生成(改玩法)分流——有界单文件重写 game-logic.js,复用 cheap_studio resume + 三层校验。
if mode == "regenerate-module":
@ -346,6 +352,9 @@ def _process_regenerate_job(state: WorkerState, job: dict, modify: dict) -> dict
"""
trace_id = job.get("traceId") or job.get("job_id")
game_id = job.get("gameId") or job.get("job_id")
# 真后端来的 gameId 是 Java Long → JSON 数字 → Python intcheap_run 的 subprocess shell-outscaffold/build/stage/smoke/play
# 与路径段都要求 strint 会抛 TypeError(expected str, not int) → 生成静默判 llm_error。此处在 job 消费边界统一归一为 str。
game_id = str(game_id) if game_id is not None else None
import cheap_run