Skip to content

feat(scheduler): 任务级参考图 labels + jitter 顶层契约 — image_ref_labels/jitter_minutes 全链路 (PR-B5)#157

Merged
sweetcornna merged 1 commit into
mainfrom
feat/scheduler-image-ref-labels
Jul 18, 2026
Merged

feat(scheduler): 任务级参考图 labels + jitter 顶层契约 — image_ref_labels/jitter_minutes 全链路 (PR-B5)#157
sweetcornna merged 1 commit into
mainfrom
feat/scheduler-image-ref-labels

Conversation

@sweetcornna

Copy link
Copy Markdown
Owner

PR-B5:定时任务级参考图 labels + jitter 的后端 API 契约

image_ref_labels / jitter_minutes 提升为调度任务 API 的顶层字段,打通前端(#151/#154 已备好线型与组件)→ builtin 的链路。基于 #155 多样性引擎(_jitter_secs_from_metadata / QZONE_DAILY_DIVERSITY_TAIL 已在),本 PR 只做衔接。

改动

infra/_scheduler_lib.py

  • NewJobBody / EditJobBody / JobOut 新增可选顶层字段 image_ref_labels: list[str] | Nonejitter_minutes: int | None(默认 None,契约安全)。
  • _compose_metadata:两个 B5 字段用显式赋值(非 setdefault)写进 job metadata——顶层字段权威覆盖 metadata 里的旧值;顶层为 None 时不覆盖既有 metadata 值(这正是 PATCH 省略字段不丢的机制)。
  • _validate_qzone_daily:labels 每个过资产 label 形状校验(_ASSET_LABEL_RE = [a-z0-9_-]{1,64},对齐 routes_admin_a/studio/_personas_lib.py::_LABEL_PATTERN)且数量 ≤8(_MAX_IMAGE_REF_LABELS,对齐 corlinman_agent.image.dispatch._MAX_REFS);jitter_minutes0..180_JITTER_MINUTES_MAX)。违规回 422 invalid_qzone_daily_args
  • JobOut 序列化经新 _read_image_ref_labels / _read_jitter_minutes 从 metadata 读回回显(防御式:形状不对→None)。
  • _set_enabled_route resume 再校验、_load_template_body 模板解析都透传两字段。

infra/scheduler.py(PATCH edit_job

scheduler/builtins/qzone_daily.py

  • _resolve_image_ref_labels(metadata) 读非空 list[str]_compose_image_ref_block 渲染参考图指令段。
  • _compose_system_prompt普通 tail 与多样性 tail 之后都追加该段:"如需配图:image_with_refs 的 characters 必须用这些参考图标签:{labels};画面要像随手拍的生活切片而非摆拍合影。" best-effort,形状不对即省略,builtin 永不抛。

上传通道(读过、无需改动)

参考图走现有 persona-asset 路由 routes_admin_a/studio/personas.pyPOST 表单 kind="reference"label_validate_label[a-z0-9_-]{1,64})。image_with_refscorlinman_agent/image/dispatch.py)已按 label 解析 characters_MAX_REFS=8 截断)。调度侧只存 label 字符串,无需新端点。

JobOut 回显语义(顶层 vs metadata 的权威关系)

  • metadata 是唯一存储真相(store of record);顶层字段是它的读写投影。
  • :POST/PATCH 的顶层字段 → _compose_metadata 显式写入 metadata(覆盖旧值);顶层 None → 保留 metadata 现值。
  • JobOut.image_ref_labels / jitter_minutes 从 metadata 读回。因此 PATCH 未传的字段不丢(metadata 里的值原样回显)。

测试

  • test_admin_scheduler_qzone.py:POST 带 labels+jitter → JobOut 回显 + metadata 落库 + list 端点往返;无字段→回显 null;PATCH 改 labels(jitter/persona 不丢);PATCH 只改 jitter(labels 不丢);9 label→422;"Bad Label!"→422;jitter=999→422;负数→422;PATCH 坏 label→422 且不 mutate。
  • tests/scheduler/test_qzone_daily.py:两种 tail 后都带参考图段(含指定 labels 字面 + "随手拍的生活切片");无 labels 不含该段;_resolve_image_ref_labels 防御式清洗;builtin 端到端 prompt 携带 metadata labels。

验证

  • uv run ruff check(改动文件干净;仓库内唯一 ruff 报错在未触及的 config_admin/models.py,base HEAD 即存在的既有债)
  • uv run mypy python/packages/ 全绿(609 files)
  • uv run lint-imports 2 kept / 0 broken
  • env -u ANTHROPIC_BASE_URL uv run pytest .../test_admin_scheduler_qzone.py .../tests/scheduler/ -q → 166 passed

与规格的偏差

无功能偏差。补充项:_load_template_body_set_enabled_route 也透传/再校验两字段(规格未明列,为契约一致性顺带覆盖,低风险)。

…r_minutes 全链路

NewJobBody/EditJobBody/JobOut 新增可选顶层字段 image_ref_labels / jitter_minutes;
_compose_metadata 用显式赋值让顶层字段权威覆盖 metadata 旧值(None 时不覆盖);
_validate_qzone_daily 校验 label 形状([a-z0-9_-]{1,64})+数量≤8、jitter 0-180 → 422;
JobOut 从 metadata 读回回显;PATCH 合并透传,jitter 变更经 _apply_enabled_state
重建 runner loop 的 jitter_secs(复用 #155 _jitter_secs_from_metadata)。

builtin 组 system prompt 时读 image_ref_labels,在普通/多样性两种 tail 后追加
参考图指令段(best-effort,形状不对即省略,永不抛)。

上传通道复用现有 persona-asset 路由(kind=reference),调度侧只存 label 字符串。
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@github-actions github-actions Bot added codex:needs-review A Codex review is needed for the current PR head. codex:review-requested A Codex review was requested or should be running automatically. status: 🔁 re-review loop A fresh Codex review was requested after the latest change or comment. codex:reviewed Codex posted a review result or thumbs-up after the latest request. status: 👀 ready for maintainer look No automation blocker is known; a maintainer should inspect the current result. and removed codex:review-requested A Codex review was requested or should be running automatically. codex:needs-review A Codex review is needed for the current PR head. status: 🔁 re-review loop A fresh Codex review was requested after the latest change or comment. labels Jul 18, 2026
@sweetcornna
sweetcornna merged commit cc7573b into main Jul 18, 2026
8 of 9 checks passed
@sweetcornna
sweetcornna deleted the feat/scheduler-image-ref-labels branch July 18, 2026 18:12
@github-actions github-actions Bot added the status: ✅ merge-ready Evidence and review are clear; normal merge gates may proceed. label Jul 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

codex:reviewed Codex posted a review result or thumbs-up after the latest request. status: ✅ merge-ready Evidence and review are clear; normal merge gates may proceed. status: 👀 ready for maintainer look No automation blocker is known; a maintainer should inspect the current result.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant