Repository navigation
fix(schedule): 冷段细化贴段首,避免窗口被夹到段尾 - #7
Conversation
_refine 里 target 由 seg_start 替换 hour 得到,段首晚于偏好时刻时 target 加一天会落到段外,再被 latest_start 夹到 f_end-need, 整段空闲只用到最后 run_estimate。改为 target = seg_start。 docs: README 去掉与当前实现不符的描述并精简,pyproject 下限对齐 3.11
Reviewer's Guide本 PR 修复了空闲窗口细化在偏好时刻早于冷段段首时的起点计算错误,使调度能够利用完整冷段而非退化为段尾短窗口;同时纠正文档与当前空闲窗口实现的偏差,并将项目 Python 支持下限和锁定依赖统一到 3.11+。 Flow diagram for corrected idle-window refinementflowchart TD
A["冷段开始 seg_start"] --> B["计算偏好时刻 target"]
B --> C{"target < seg_start"}
C -->|是| D["target = seg_start"]
C -->|否| E["保留 target"]
D --> F["计算 latest_start"]
E --> F
F --> G["计算 start_ts"]
G --> H["利用冷段并预留 buffer 与运行时间"]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 3 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="amrita_plugin_memory/rethinking/schedule.py" line_range="533" />
<code_context>
)
if target < seg_start:
- target += timedelta(days=1)
+ target = seg_start
# 起点尽量靠近偏好时刻,但必须落在空闲段内且留够运行空间
latest_start = max(f_start, f_end - need * 60)
</code_context>
<issue_to_address>
**Preferred run starts too early**
When a cold segment crosses midnight and the preferred hour falls after midnight within that segment, `_refine` assigns `seg_start` to `target`, so `start_ts` schedules the run from the segment head (for example, 22:00) instead of the preferred time (03:00), even though that time falls within the segment.
Keep the next-day preferred target when it falls within the cold segment instead of unconditionally assigning `seg_start`.
</issue_to_address>
### Comment 2
<location path="README.md" line_range="498" />
<code_context>
-| 代码质量 | Ruff + Pyright |
+| 组件 | 技术 |
+| ---------- | ----------------------------------------------------------- |
+| 运行时 | Python 3.11+ / NoneBot2 / AmritaCore |
+| 向量库 | ChromaDB(PersistentClient 或 HttpClient) |
+| 嵌入 | OpenAI Embedding / Ollama Embedding |
</code_context>
<issue_to_address>
**Installation rejects stated Python versions**
When a user follows the README runtime requirement on Python 3.14 or later, the README says Python 3.11+, but `pyproject.toml` limits `requires-python` to `<3.14`, so package installation rejects a runtime the README says is supported.
Make the README runtime requirement match `pyproject.toml`, or update the package metadata to support the versions stated in the README.
</issue_to_address>
### Comment 3
<location path="README.md" line_range="573" />
<code_context>
| `decay.sweep_interval_hours` | `24` | 分层清理周期(小时) |
| `decay.sweep_batch_limit` | `5000` | 单次清理最多扫描的记忆条数 |
-| `per_session_memory_limit` | `50` | 单个分区(uni_id)的记忆条数上限 |
+| `per_session_memory_limit` | `100` | 单个分区(uni_id)的记忆条数上限 |
| `memo_max_chars` | `1000` | L1 备忘录字数硬上限 |
-| `enabled` | `false` | 是否启用离线巩固循环 |
</code_context>
<issue_to_address>
**Config metadata still says 50**
When a consumer displays the `ConfigFile` field description, `ConfigFile.per_session_memory_limit` has a default of 100, but its Pydantic field description still says the default is 50; consumers that display the config metadata are given a value that conflicts with the README and runtime default.
Update the field description to say the default is 100.
</issue_to_address>Sourcery assessment
Needs a human reviewer. 2 findings to address first, and when the preferred hour falls before a selected idle segment, the scheduler will now start at the segment’s beginning instead of clamping the run toward its end; if that timing is wrong, the agent could send a user-facing message earlier than intended. Reverting restores the prior scheduling behavior, but cannot retract a message already sent.
Blocking findings: amrita_plugin_memory/rethinking/schedule.py:533, README.md:498
Sourcery review 指出 target=seg_start 会把 22:00-09:00 这种跨午夜段的起点 拉到段首 18:00/22:00,而 03:00 其实就在段内。改为次日偏好时刻仍在段内 (nxt < seg_end)时取 nxt,两次都不在段内才退到段首。 顺带修正 config 里 per_session_memory_limit 的描述(写的是 50,实际 100), README 的 Python 版本改成 3.11-3.13 与 requires-python 的 <3.14 对齐。
|
三条都处理了,push 在 5c3a549。 Comment 1 — 跨午夜冷段起点被贴到段首:这条是对的,而且比我原来那个修改更严重。我复现了:只让 09:00–18:00 活跃,冷段是 18:00 到次日 09:00,原实现给出 修法不是回退成 if target < seg_start:
nxt = target + timedelta(days=1)
target = nxt if nxt < seg_end else seg_start三种情况都验过:跨午夜且 03:00 在段内 → 起点 03:00;冷段 04:00–08:00 且偏好时刻在段外 → 起点 04:00 用满 225 分钟;段内且不跨午夜 → 03:00 不变。Sourcery 提到的「可能比预期更早给用户发消息」正是修掉的行为,现在不会了。 Comment 2 — README 说 3.11+ 但 metadata 是 <3.14:改成 Comment 3 — ConfigFile 的字段描述写 50:改成 100。这个是我改文档时只改了 README、漏了代码里的 description,确实会误导看配置元信息的人。 回归验证:300 组随机不变量仍零失败,二分与暴力解一致,30 天密度下 200 次规划平均 3.1 ms,ruff 与 py_compile 干净。 |
概要
修
IdlePlanner._refine里的一处窗口起点夹取错误,顺带把 README 里跟当前实现不符的描述改掉并精简,requires-python下限对齐 3.11。调度修正
_refine先用seg_start.replace(hour=target_hour)算偏好时刻,段首晚于偏好时刻时target += timedelta(days=1),于是 target 落到段外,随后被latest_start = max(f_start, f_end - need*60)夹到段尾 —— 整段空闲只用到最后那点。复现:只让 00:00–04:00 与 09:00–24:00 活跃,冷段是 04:00–08:00 一整块。
原实现给出
07:35–07:45(10 分钟),改后给出04:00–07:45(225 分钟)。影响不只在窗口长度:07:35 起跑意味着 DMN 顶在用户起床前,尾部 buffer 刚好被吃掉,
一旦超时就撞上用户第一句话,而这块本来有四个小时可以安排。
修法只有一行,
if target < seg_start: target = seg_start。验证
非强制时不落进活跃时段,零失败
merge_noise与二分结果对照暴力解,5 组随机样本一致ruff check/ruff format --check通过,全量py_compile通过文档
README 从 766 行压到 727 行,改动以删除和纠错为主:
per_session_memory_limit默认值 50 改成实际的 100SubconsciousState.payloadsubconscious_get_contextcurrent_date,不再是last_run/total_tokens那套.env表重复的嵌入配置表、三层模型的大图(改成三句话)、配置表里 18 行 idle 逐项(改成指向
SubconsciousConfig)依赖
requires-python从>=3.10提到>=3.11:chromadb 1.5.9 自身虽然写的是>=3.9,但它拉进来的 numpy 2.4 / onnxruntime 1.30 / sqlalchemy 2.1 都是
>=3.11,声明 3.10 会在解析阶段就失败。
uv.lock随之重解,移除 py3.10 分支(-782 行)。[tool.ruff] target-version保持py310未动 —— 提到 py311 会让 UP017 对timezone.utc批量报错,那是另一件事,不该混进来。Review 关注
有对应用例覆盖
uv.lock变动较大但都是 py3.10 分支清理,185 个包与本地环境一致Summary by Sourcery
修正冷段窗口起点规划并同步项目文档与 Python 依赖版本要求。
Bug Fixes:
Enhancements:
Build:
Documentation: