Skip to content

feat(persona): 生活节奏信号 compute_life_signals — 外出逾期/同状态过久/在外过久三档 nudge#152

Merged
sweetcornna merged 1 commit into
mainfrom
feat/persona-life-signals
Jul 18, 2026
Merged

feat(persona): 生活节奏信号 compute_life_signals — 外出逾期/同状态过久/在外过久三档 nudge#152
sweetcornna merged 1 commit into
mainfrom
feat/persona-life-signals

Conversation

@sweetcornna

Copy link
Copy Markdown
Owner

目标

移植 hermes 的「生活节奏信号」(life signals)到 corlinman persona 人生系统 —— QZone 内容反死板改造(PR-B2)的核心件之一。让被绑定的 persona 感知到自己"太久没出门 / 一直待在同一状态 / 在外太久",并在写每日说说时优先响应这种节奏提示。

移植来源:hermes grantly_life_tool.py:237-333_compute_life_signals(源文件本地只剩 .pyc,按编排下发的权威规格实现),去掉「学院/格兰」硬编码,改为 persona 通用文案。

改动

corlinman-agent — persona/life.py

  • 新增常量:_OUTING_STATES = {"on_mission", "traveling"}_OUTING_OVERDUE_DAYS=13_SAME_STATE_STALE_DAYS=6_OUTING_TOO_LONG_DAYS=8
  • 新增纯函数 compute_life_signals(life, now) -> dict(不做 IO、永不抛异常):
    • days_in_current_state —— 距 current["since"] 的整天数;
    • days_since_last_outing —— 当前在外→0;否则取 history 中最近一次涉及外出状态的转场;再否则回退到"最老的已知时间戳"锚点(保证从未用过外出状态的 persona 追踪够久后仍能触发 go_out);无任何可用时间戳→省略;
    • 可选 life_nudge = {level, kind, message, suggested_action},三档:
      • ≥13 天没出门 → level=high, kind=go_out
      • ≥8 天处于外出状态 → level=medium, kind=wrap_outing
      • ≥6 天同状态 → level=medium, kind=change_scene
      • 优先级:HIGH 覆盖 MEDIUM;同为 MEDIUM 先判 wrap_outing(在外太久比换场景更具体)。
    • message/suggested_action 为 persona 通用文案,suggested_action 引导模型调用 persona_life_event_seed / persona_life_set_state 推进状态。
    • 坏时间戳 / 缺字段 → 省略对应信号;非 dict / 空 life → {}
  • dispatch_persona_life_get 成功包并入 signals(防御性 try/except,dispatcher 永不抛异常)。

corlinman-server — scheduler/builtins/qzone_daily.py

  • _resolve_life_block 的 strategy 2(读运行时 persona-state store)拉到 life doc 后,追加"节奏"两行(当前状态已持续:N 天 / 距上次外出:N 天),命中 nudge 时再加一行 ⚠ 生活节奏提示(优先响应):{message}
  • 新增 _life_signals() 帮手:lazy + try/except 的 server→agent import(层级契约允许该方向);全 best-effort,任何失败即省略。不触碰 fix(scheduler): qzone 日常发布 tid/qzone_url 采集 — ToolResultEvent payload 转发 #150 的 harvest 逻辑。

验证

结果
ruff check(4 个改动文件) ✅ All checks passed(仓库既有 config_admin/models.py import-order 债未碰)
mypy python/packages/ ✅ Success: no issues found in 609 source files
lint-imports ✅ 2 contracts kept, 0 broken
pytest(目标两文件) ✅ 46 passed
回归(persona_life / qzone_daily / agent_servicer 路由 / gf_persona_seed) ✅ 111 + 7 passed

life doc 真实字段确认

  • life["current"]state(∈ _ALLOWED_STATES)、locationactivitycompanionsmoodweathersince(tz-aware ISO,_now_iso())、until_estimatestory_arc
  • life["history"][{ts, from:<prev current>, to:<new current>, reason}]
  • 时间字段即 current["since"] 与 history 的 ts;外出状态 = state ∈ {on_mission, traveling}。均按此实现,无臆造字段。

与规格的偏差

  • level 取小写 "high"/"medium"(与 kind 的小写风格一致;规格散文里写作 HIGH/MEDIUM 系强调)。除 qzone 块只用 message 外无下游消费者。
  • days_since_last_outing 的"从未外出"锚点:规格未细定,本实现回退到最老已知时间戳,使"从不外出"的 persona 追踪够久后仍触发 go_out(读作略松,但只驱动正确 nudge、从不驱动错误 nudge)。

移植 hermes grantly_life_tool.py:237-333 的 _compute_life_signals 到 corlinman
persona 人生系统,去掉学院/格兰硬编码,改为 persona 通用文案。

- corlinman-agent persona/life.py: 纯函数 compute_life_signals(life, now),返回
  days_in_current_state / days_since_last_outing + 可选 life_nudge(三档:
  ≥13天没出门=HIGH go_out;≥8天在外=MEDIUM wrap_outing;≥6天同状态=MEDIUM
  change_scene;HIGH 覆盖 MEDIUM,同 MEDIUM 先判 wrap_outing)。坏时间戳/缺字段
  即省略对应信号,永不抛异常、不做 IO。dispatch_persona_life_get 成功包并入 signals。
- corlinman-server qzone_daily.py::_resolve_life_block: 追加节奏两行 +(命中时)
  ⚠ 生活节奏提示行;lazy+guarded server→agent import,全 best-effort。
- 测试:agent 侧分档表 + dispatch get;server 侧 qzone_daily 命中 nudge 的 prompt。
@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 dd911ca into main Jul 18, 2026
8 of 9 checks passed
@sweetcornna
sweetcornna deleted the feat/persona-life-signals branch July 18, 2026 17:38
@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