Conversation
hallerite
force-pushed
the
feat/agent-budgets-completion
branch
from
September 15, 2026 11:43
8aeca4d to
9df8af8
Compare
hallerite
force-pushed
the
feat/agent-budgets-completion
branch
4 times, most recently
from
September 15, 2026 17:40
860d824 to
9ffcfdf
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 80074b7. Configure here.
…e and answer
Evidence: the search-QA delegation probe (openseeker/redsearcher, GLM-5.3). A general
delegation paragraph takes spawning from 4 % to 89 % of episodes and the children are
used well, but the parent has no cheap way to keep a long-running child in view: a
"verify five priors" child consumed 14 of a 35-turn tree unnoticed, and 22 % of
delegating episodes ran into the rollout cap. Every completion also cost the parent an
inbox.read -> agent.get -> result() round trip because the event carried only
{agent_id, status}.
- `rlm.watch.agent(child, every_turns=N, every_tokens=M)`: a `watch.progress` inbox
event each time the child's own model calls or new tokens cross the next multiple,
with turns, tokens, name, status and the history slice start:end since the previous
event. The parent reads `child.history().messages[start:end]` and steers
(`child.steer("report what you have and stop")`) if the child should wrap up. No hard
per-child budget: the child stays autonomous, the parent stays informed. Without
thresholds watch.agent behaves as before.
- `agent.completed` content now carries name, turns, error and the last 4 KiB of the
child's answer next to agent_id and status, mirroring shell.completed's output tail;
`await child.result()` still holds the full answer.
Supervisor keeps per-agent turn/new-token counters (record_call now takes the calling
agent's id); a new subscription kind "progress"; the guide documents both.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
spawn(name=...) reserves the name for the session, so it is as immutable as the id and belongs on the handle; the model treats it that way already — 37 AttributeErrors on `.name` across 36 delegating episodes (`[c.name for c in children]`). spawn() and get() populate it; the guide lists the handle's fields. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
result() mirrors ShellJob.result(): it waits up to yield_after seconds (default 300) for the child to finish and always returns an AgentResult with status, answer, usage, turns and session_dir; answer is None and running is True while the child is still working on its first answer, instead of a bare None. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The watch.progress check moves from the model-call accounting to the agent-step publish point, so the event's start:end slice includes the step that crossed the threshold. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A child's report arrives as {"agent_id", "name", "text"} instead of a bare string, so parents can treat every event's content the same way.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…for interim findings The leaf guide framed send_to_parent as the way to report, so children sent the report and then repeated it as their answer, and the parent read both. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
hallerite
force-pushed
the
feat/agent-budgets-completion
branch
from
September 16, 2026 00:39
5cbf523 to
4bc5694
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Stacked on #184 (base
feat/runtime-instructions). Multi-agent follow-ups from the search-QA probe, kept separate from the SWE consolidation in #184.What
rlm.watch.agent(child, every_turns=N, every_tokens=M): awatch.progressinbox event each time the child's own model calls or new tokens cross the next multiple, withturns,tokens,name,statusand the history slicestart:endsince the previous event. The parent reads(await child.history()).messages[start:end]and steers (await child.steer("report what you have and stop")) if the child should wrap up. No hard per-child budget: the child stays autonomous, the parent stays informed.watch.agent(child)without thresholds is unchanged.agent.completedcontent now carriesname,turns,errorandanswer(the last 4 KiB of the child's answer) next toagent_idandstatus, mirroring the output tail onshell.completed.await child.result()still holds the full answer.AgentHandlecarriesname(set byspawn()/get()): the sibling name is reserved for the session, so it is as immutable asid; the model already assumed it (37AttributeError: 'AgentHandle' object has no attribute 'name'across 36 delegating episodes).await child.result(yield_after=300)mirrorsShellJob.result(): it waits up toyield_afterseconds for the child to finish and always returns anAgentResult(status,answer,usage,turns,session_dir,running). While the child is still working on its first answer,answerisNoneandrunningisTrue, instead of a bareNonethe model read as failure (6 crashes in the delegate2 run). A persistent child's latest answer stays available while it runs again; terminal failure/cancellation raises.agent.messagecontent is a dictionary like every other inbox event:agent_id,name,text. It was the one event whose content was a bare string, and parents iterating their inbox called.get()on it (4 episodes in the redsearcher delegate2 run).agent.completedand throughresult());send_to_parentis for interim findings, blockers or questions. The old wording ("put a report in your parent's inbox") made children send the report and then repeat it as their answer, so the parent read it twice.AgentInfo.turns: the child's own model-call count onlist()/get()/info().watch.progressfires from the agent-step publish point, after the step that crossed the threshold is logged, so the event'sstart:endslice includes it (it used to fire at model-call time, one step early).record_callnow takes the calling agent's id); new subscription kindprogress; broker accepts optionalevery_turns/every_tokensonwatch.agent; guide documents both.Why
Search-QA delegation probe with GLM-5.3 on openseeker/redsearcher (nano-rlm head 11729d5,
search+fetchskills, depth 1, ≤2 concurrent children): a general delegation paragraph takes spawning from 4 % to 89 % of episodes and the children are used well — self-contained briefs, parallel work, results collected, children reporting up withsend_to_parentin 80/87 episodes. But the parent has no cheap way to keep a long child in view: it polledrlm.agent.list()467 times and readhistory()146 times across 87 episodes and never usedwatch.agent; a "verify five priors" child consumed 14 of a 35-turn tree unnoticed; 22 % of delegating episodes ran into the rollout cap. Steering does happen when the parent notices ("Please wrap up now and send your final report immediately…", 7 uses), so the missing piece is the notice, not the control. The completion event carried only{agent_id, status}, so every completion cost aninbox.read→agent.get→result()round trip. Per-episode review:rlm-v2-study/usage/redsearcher-spawn-37d37b40-review.md.Tests
test_progress_thresholds_fire_on_turn_and_token_multiples(registry unit test), the real-kernel subscription test now also registerswatch.agent(child, every_turns=1)and checks thewatch.progresscontent, and the extended completion-event assertions intest_messaging.py. Full suite passes with the load-sensitive MCP cancel test deselected (as on #184). Imports verified under Python 3.10 (sandbox interpreter).🤖 Generated with Claude Code
Note
Medium Risk
Changes public delegation and inbox event shapes (especially
result()no longer returningNoneand structuredagent.messagecontent), which can break callers that assumed the old behavior.Overview
Improves parent visibility and control over delegated agents without changing the basic spawn/send/steer model.
await child.result(yield_after=…)now mirrors shell jobs: it can wait up to 300s (default) and always returns anAgentResultwithstatus,answer,usage,turns,session_dir, andrunning—no moreNonewhile the child is still on its first answer.AgentHandle.nameandAgentInfo.turnsexpose sibling names and per-child model-call counts on handles and metadata.Watching:
rlm.watch.agent(child, every_turns=N, every_tokens=M)registersprogresssubscriptions that emitwatch.progresswhen the child’s own turns or new tokens cross multiples, including a historystart:endslice (fired after the step is logged). Plainwatch.agent(child)is unchanged.Inbox payloads:
agent.completednow includesname,turns,error, and a 4 KiB answer tail;agent.messagecontent is a dict (agent_id,name,text) like other events. Guides and README reflect these shapes and clarify thatsend_to_parentis for interim updates, not duplicating the final answer.Supervisor/broker wiring adds
yield_afteronagent.result, per-agent turn/token accounting inrecord_call, and subscriptionprogresslifecycle on agent teardown.Reviewed by Cursor Bugbot for commit 4bc5694. Bugbot is set up for automated code reviews on this repo. Configure here.