feat: support RLM training over ACP - #2386
Conversation
b1fd0ff to
44a4a13
Compare
24a3788 to
fc90deb
Compare
44a4a13 to
9e4ea9b
Compare
6cb8830 to
edbe71a
Compare
9e4ea9b to
bbaea73
Compare
edbe71a to
4ab0bdc
Compare
3f8ca38 to
4b4b1ac
Compare
eb232a8 to
1b401b7
Compare
1b401b7 to
dcadf55
Compare
| @@ -253,9 +261,21 @@ async def _stop(self, *, graceful: bool) -> None: | |||
| return | |||
| try: | |||
| if graceful and reader is not None: | |||
There was a problem hiding this comment.
🟡 Medium acp/__init__.py:263
Graceful close swallows exceptions from acp_close_metrics and trace.record_metrics, so invalid close metadata or metrics make the session appear to close successfully while final RLM metrics are silently absent. Limit the best-effort except to shutdown transport, allowing metric validation and recording failures to propagate.
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @verifiers/v1/acp/__init__.py around line 263:
Graceful close swallows exceptions from `acp_close_metrics` and `trace.record_metrics`, so invalid close metadata or metrics make the session appear to close successfully while final RLM metrics are silently absent. Limit the best-effort `except` to shutdown transport, allowing metric validation and recording failures to propagate.
| ) | ||
| if idempotent is None: | ||
| idempotent = IdempotentRequest(binding=binding) | ||
| session.idempotent_requests[idempotency_key] = idempotent |
There was a problem hiding this comment.
🟠 High interception/server.py:438
Each distinct client-supplied Idempotency-Key adds an entry to session.idempotent_requests that retains the full response.raw for the rollout, so a long-running harness with fresh keys grows memory without bound and can OOM the shared interception server. Add a bounded or expiring replay cache, or evict entries once their replay guarantee is no longer needed.
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @verifiers/v1/interception/server.py around line 438:
Each distinct client-supplied `Idempotency-Key` adds an entry to `session.idempotent_requests` that retains the full `response.raw` for the rollout, so a long-running harness with fresh keys grows memory without bound and can OOM the shared interception server. Add a bounded or expiring replay cache, or evict entries once their replay guarantee is no longer needed.
Summary
ai.prime.rlm/runtime-v1payload through ACPsession/newsession/closemetadata through the generic runner and let the RLM harness validate its own finalai.prime.rlm/session-v1snapshot into training metricsIdempotency-Keyin the interception server by coalescing in-flight retries and replaying completed non-streaming responses within one rollout7a26d3c2cd2f38e11807ef7b88ce4ea197552ea8until the companion Nano PR mergesVerifiers does not model RLM lineage, compaction, subagents, or ACP lifecycle artifacts. Those semantics stay inside Nano; Verifiers only transports standard ACP close metadata and standard HTTP idempotency.
Contract
This intentionally requires the new Nano contract and contains no backwards-compatibility path. Land PrimeIntellect-ai/nano-rlm#134 before this PR, then remove the temporary CI commit pin once Nano main contains the contract.
Validation
pytest tests/v1/test_idempotency.py -q— passed against a real loopback interception server