diff --git a/internal/agent/core/inputroute_test.go b/internal/agent/core/inputroute_test.go index a2c378b..e79d5cc 100644 --- a/internal/agent/core/inputroute_test.go +++ b/internal/agent/core/inputroute_test.go @@ -34,6 +34,11 @@ func TestResident_InputchRoutingIsExclusive(t *testing.T) { if got := parent.DumpScheduler().Stats.Enqueued; got != before { t.Fatalf("划给子的 inputch,父不应再入队(before=%d after=%d)", before, got) } + // 轮次必须真的涨:此前 info() 根本没填 Rounds ⇒ 父永远读到 0 + // (现场:子处理表已有 2 条,轮次却显示 0,被误判成"子没干活")。 + if got := parent.residents["r-route"].info().Rounds; got <= 0 { + t.Fatalf("子处理的轮次应 > 0,实际 %d", got) + } } // 归属到一个不存在(或已销毁)的 agent 时**不吞输入**:父兜底处理。 diff --git a/internal/agent/core/resident.go b/internal/agent/core/resident.go index caaabf0..dcb0a55 100644 --- a/internal/agent/core/resident.go +++ b/internal/agent/core/resident.go @@ -504,6 +504,13 @@ func (rc *residentChild) info() ResidentInfo { ID: rc.id, State: state, InputChs: append([]string(nil), rc.inputChs...), AllowedOutputs: append([]string(nil), rc.allowed...), ContextFull: full, CreatedAt: rc.createdAt, TableSize: len(table), + // Rounds = 子**已执行的轮次数**(调度器的执行计数,单调不减)。 + // + // 此前这里根本没填这个字段 ⇒ 父看到的永远是 `轮次=0`,与"处理表已有 N 条" + // 自相矛盾(现场:子明明处理了两轮,父读到 rounds=0,误判成"子没干活")。 + // 注意它**不等于** len(table):处理表记的是"当前上下文窗口内"的轮次, + // 压缩会清空(§8.3),所以窗口内的条数会被重置,而轮次总数不会。 + Rounds: rc.agent.roundsExecuted(), } if len(table) > 0 { info.Table = table diff --git a/internal/agent/core/scheduler.go b/internal/agent/core/scheduler.go index 97dc2b1..e899636 100644 --- a/internal/agent/core/scheduler.go +++ b/internal/agent/core/scheduler.go @@ -745,6 +745,18 @@ func newKernelInterruptTask(evt *agentIO.InputEvent) *Task { } // DumpScheduler 返回调度器的原子快照(供状态页/测试断言)。 +// roundsExecuted 返回本 agent 已执行的轮次数(供驻留子状态面展示)。 +// +// 一轮 = 一次被执行的输入(排队与中断都算)。为什么不用 inputch 处理表的条数: +// 那张表记的是"当前上下文窗口内"的轮次,压缩会清空(设计 §8.3)—— +// 拿它当轮次会让父看到轮次倒退。 +func (a *Agent) roundsExecuted() int { + if a.sched == nil { + return 0 + } + return int(a.DumpScheduler().Stats.Executed) +} + func (a *Agent) DumpScheduler() SchedulerSnapshot { if a.sched == nil { return SchedulerSnapshot{}