mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 05:21:57 +00:00
85eee89799
入口的 history 只取这一轮之前的、只有问数据的对话能发起
A1 并发发起不原子(复核实测:同一对话同时两次新问都 202、两轮 seq 都是 0;同一轮同时 3 次重试 [500, 202, 202],同一轮建两次图、
停止只停了后一个;写 turn.attempt 撞号时任务已提交成排队却没有后台任务,这段对话从此一直「正忙」):
- 发起的核对和写入(这段对话忙不忙、下一轮排第几、轮次、任务、这一次尝试的第一条事件 turn.attempt)放进一个事务,第一句先占住
这段对话(hold_conversation:SQLite 上拿到写锁、PostgreSQL 上锁住这一行),同时来的几次一个接一个,后来的看得见先来的写下的;
重试、接着收尾的那一轮占住之后重读,任务按「不在排队、不在跑」条件更新、看 rowcount;写不进去整个事务回滚,什么都不留下。
继续运行要先续上那次运行(它用自己的会话写库,不能放进占着对话的事务),续上了却没排上队的把它取消;挂起旧运行的取消挪到
提交之后(只有排上队的那一次去取消)。页面打开时自动发的接着收尾占锁时不改活跃时间。
- conversations.new_turn 先记活跃时间再数 seq(第一句写就占住这段对话),老页面的开轮接口也不再撞号。
- 事件的 seq 由任务行上的计数器发(UPDATE … SET last_seq = last_seq + 1 RETURNING),同一轮同时追加的几处各拿不同的号。
- ChatTurnManager.start:同一轮在这个进程里还有后台任务活着就不起第二个、不覆盖登记;上一次的任务刚记完结局还没退出时等它退出再起。
A2 使用者(user 角色)现在能「继续运行」了:以前 POST /api/runs/{id}/continue 对它是 403(只放行停止),问数据这里照原说法回 403
role_required,运行不动;重试本轮、重新运行本轮照常。
A3 晚到的复核:先写库、发 review.late,再出登记、叫醒订阅方(以前反过来,开着的实时流先收到 stream.end 走掉);那一行的几处写入
(任务、晚到的复核、下一次尝试)先占住那一行再读改写(hold_turn),用量改成按增量记在库里那一份上(以前任务开始时拿一份拷贝、
之后整块盖回去,重试时晚到复核记的那笔会被盖掉);自动重来时换下来的那次运行交出去之后不再当这一次的运行记一遍。
A4 运行入口的 history 只取这一轮之前的:新的 conversations.run_history 照以前页面 historyOf 的规则(答案没有用说明、都没有的跳过、
每轮截 600 字、最多 6 轮),重试、重新运行较早的一轮时后面几轮不再进它的入口。
A5 只有问数据的对话(kind=chat)能发起一轮,别的种类 422 chat_turn_invalid。
测试:tests/test_chat_turns_races.py(asyncio.gather 并发两次新问、三次重试、两个标签页接着收尾、二十次并发追加事件;发起写到一半
出错什么都不留下;后台任务不起第二个;使用者继续运行 403 且说法同 /runs;开着的流收到 review.late;重试不丢晚到复核的用量;
history 只取之前的、截 600 字、跳过没答案的;重新运行较早的一轮不带后面几轮;只认问数据的对话)。先写测试,12 条都失败;去掉
占锁、计数器、不起第二个、先写库再叫醒、增量记用量、同一事务、按 seq 截这几处修复分别回跑,对应的测试都会失败。