From 825ec687e2449cdfb47028f93da70f24d7ae4a8a Mon Sep 17 00:00:00 2001 From: James Wiesebron Date: Thu, 25 Jun 2026 21:32:25 -0700 Subject: [PATCH 1/2] feat(#3279): compute + inject EGG_RESEED_THRESHOLD per event spawn The in-pod resume-vs-reseed gate (#3200 slice-8) and the #3249 measurement resolve their threshold via egg_agent.reseed.resolve_reseed_threshold, which reads $EGG_RESEED_THRESHOLD first and otherwise tries to import orchestrator.agent_model_resolution.reseed_threshold. The agent pod runs with orchestrator off PYTHONPATH, so without the override the threshold resolves to None and the gate takes its no_threshold safe-reseed branch every event. Compute reseed_threshold(decision.claude_code_alias) in _build_event_spawn_params (the orchestrator has the model decision; the pod can't) and inject it as EGG_RESEED_THRESHOLD in the event pod env. Resolved against claude_code_alias so the injected value matches the --model flag and the emitted #3249 measurement, and sub-1M LiteLLM models resolve against their real backend window rather than the [1m]-implied 1M. Inert unless a discipline/resume/measurement flag is on in the pod. Session-state / transcript persistence (the rest of the warm-resume substrate) is #3278. --- orchestrator/concurrent_executor.py | 30 +++++++-- .../tests/test_concurrent_executor.py | 64 +++++++++++++++++++ 2 files changed, 90 insertions(+), 4 deletions(-) diff --git a/orchestrator/concurrent_executor.py b/orchestrator/concurrent_executor.py index bdcbbc3ec0..aea834ee72 100644 --- a/orchestrator/concurrent_executor.py +++ b/orchestrator/concurrent_executor.py @@ -37,6 +37,7 @@ def get_logger(name: str, **kwargs) -> logging.Logger: # type: ignore[misc] UPSTREAM_ANTHROPIC, AgentModelDecision, classify_model, + reseed_threshold, resolve_agent_model, ) from consensus_wrapper import build_consensus_wrapped_command @@ -153,7 +154,15 @@ def spawn_event( # ``spawn_event_job`` via ``event_action`` below), not on an # ownership flag — the EGG_EVENT_LOOP_OWNER env was retired in #3164. env = self._ex.get_agent_env(agent_role) - command, upstream, upstream_model = self._ex._build_event_spawn_params(agent_role) + command, upstream, upstream_model, threshold = self._ex._build_event_spawn_params( + agent_role + ) + # Export the per-model reseed threshold so the in-pod resume-vs-reseed + # gate (#3200 slice-8) and the #3249 measurement resolve a real-window + # boundary instead of None (the gate's ``no_threshold`` safe-reseed + # branch). Inert unless a discipline/resume/measurement flag is on in the + # pod — the only consumers read it (#3279); a plain default pod ignores it. + env["EGG_RESEED_THRESHOLD"] = str(threshold) return self._ex.spawn_fn( role=agent_role, branch=branch, @@ -562,8 +571,8 @@ def stop_event_loop(self) -> None: def _build_event_spawn_params( self, role: AgentRole - ) -> tuple[list[str], str | None, str | None]: - """Return ``(command, upstream, upstream_model)`` for a role's event pod. + ) -> tuple[list[str], str | None, str | None, int]: + """Return ``(command, upstream, upstream_model, reseed_threshold)`` for a role's event pod. The event-pump template composes its own per-event prompt at runtime (``invoke_agent_for_event``), so the initial prompt is irrelevant — @@ -571,6 +580,18 @@ def _build_event_spawn_params( ``upstream``/``upstream_model`` are returned only when they differ from the default Anthropic decision (mirroring ``_spawn_agent``'s conditional forwarding) so the default-Claude wire shape is unchanged. + + ``reseed_threshold`` is the per-model token-occupancy boundary the + in-pod resume-vs-reseed gate (#3200 slice-8) compares against. The + orchestrator computes it here — it has the model decision, and the + agent pod can't (``orchestrator`` is off the pod's ``PYTHONPATH``, so + ``egg_agent.reseed.resolve_reseed_threshold`` resolves ``None`` without + the ``EGG_RESEED_THRESHOLD`` override, taking the gate's ``no_threshold`` + safe-reseed branch every event). It is resolved against ``claude_code_alias`` + — the same string passed to ``--model`` and the #3249 measurement, so the + injected threshold and the emitted measurement agree by construction, and + sub-1M LiteLLM models (whose bare alias carries their real-backend identity) + resolve against their real window, not the ``[1m]``-implied 1M (#3279). """ decision = self._resolve_model_decision(role) command = build_consensus_wrapped_command( @@ -581,7 +602,8 @@ def _build_event_spawn_params( if decision.upstream != UPSTREAM_ANTHROPIC or decision.upstream_model is not None: upstream = decision.upstream upstream_model = decision.upstream_model - return command, upstream, upstream_model + threshold = reseed_threshold(decision.claude_code_alias) + return command, upstream, upstream_model, threshold def _orchestrator_side_confirm(self, tracker: Any, role: str) -> None: """Record a ``confirm``/``complete`` orchestrator-side — no pod (#3064). diff --git a/orchestrator/tests/test_concurrent_executor.py b/orchestrator/tests/test_concurrent_executor.py index 3e0d3b393a..168dd2f585 100644 --- a/orchestrator/tests/test_concurrent_executor.py +++ b/orchestrator/tests/test_concurrent_executor.py @@ -1608,3 +1608,67 @@ def test_default_recorded_on_execution(self): execution = executor._spawn_agent(AgentRole.CODER) assert execution.resolved_model == "opus" + + +class TestEventSpawnReseedThreshold: + """#3279: the orchestrator computes the per-model reseed threshold at spawn + and exports it to the event pod as ``EGG_RESEED_THRESHOLD`` so the in-pod + resume-vs-reseed gate (#3200 slice-8) and the #3249 measurement resolve a + real-window boundary instead of ``None`` (the gate's ``no_threshold`` + safe-reseed branch — ``orchestrator`` is off the pod's ``PYTHONPATH``). + """ + + def _event_spawner(self, pipeline, mock_spawn): + from concurrent_executor import ConcurrentPhaseExecutor, _ExecutorEventSpawner + from egg_orchestrator.types import AgentRole + + executor = ConcurrentPhaseExecutor(pipeline, spawn_fn=mock_spawn) + return _ExecutorEventSpawner( + executor=executor, + roles=[AgentRole.CODER, AgentRole.REVIEWER_CODE], + slice_id=None, + ) + + def test_build_event_spawn_params_returns_default_threshold(self): + """Default (opus) → ``reseed_threshold`` is the 400k floor + (``min(400k, 0.80 * 1M)``), returned as the 4th tuple element. + """ + from concurrent_executor import ConcurrentPhaseExecutor + from egg_orchestrator.types import AgentRole + + pipeline = _make_pipeline() + executor = ConcurrentPhaseExecutor(pipeline, spawn_fn=MagicMock()) + + _command, _upstream, _upstream_model, threshold = executor._build_event_spawn_params( + AgentRole.CODER + ) + + assert threshold == 400_000 + + def test_event_spawn_injects_default_threshold_env(self): + """``spawn_event`` puts ``EGG_RESEED_THRESHOLD`` in the spawn_fn's + ``extra_env`` for a default-config (opus) pipeline. + """ + pipeline = _make_pipeline() + mock_spawn = MagicMock(return_value=_kubernetes_spawn_result()) + spawner = self._event_spawner(pipeline, mock_spawn) + + spawner.spawn_event(role="coder", action="propose", dedupe_key="k1") + + env = mock_spawn.call_args.kwargs["extra_env"] + assert env["EGG_RESEED_THRESHOLD"] == "400000" + + def test_event_spawn_threshold_uses_real_window_for_sub_1m_model(self): + """A sub-1M LiteLLM model resolves against its REAL backend window, not + the ``[1m]``-implied 1M: ``kimi-k2.7-code`` → ``int(0.80 * 262_144)``. + Guards the mis-trigger bug #3200 task-2-1 calls out. + """ + pipeline = _make_pipeline() + pipeline.config.agent_models = {"coder": "kimi-k2.7-code"} + mock_spawn = MagicMock(return_value=_kubernetes_spawn_result()) + spawner = self._event_spawner(pipeline, mock_spawn) + + spawner.spawn_event(role="coder", action="propose", dedupe_key="k1") + + env = mock_spawn.call_args.kwargs["extra_env"] + assert env["EGG_RESEED_THRESHOLD"] == str(int(0.80 * 262_144)) # 209_715, NOT 400_000 From 9b52597357beea408ccc3557e0aa3b8589776dfe Mon Sep 17 00:00:00 2001 From: "egg-reviewer[bot]" <261018737+egg-reviewer[bot]@users.noreply.github.com> Date: Fri, 26 Jun 2026 04:55:53 +0000 Subject: [PATCH 2/2] Address review: cover conservative LiteLLM branch + clarify agree-by-env docstring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a third TestEventSpawnReseedThreshold case asserting an unregistered LiteLLM model (qwen3-coder-30b) resolves to the conservative 200K window, yielding EGG_RESEED_THRESHOLD=160000 — the branch an operator whose model isn't in _SUB_1M_CONTEXT_MODELS silently lands on. Refine the _build_event_spawn_params docstring: the injected threshold and the #3249 measurement agree because both consumers read the same EGG_RESEED_THRESHOLD env var first, not because each independently re-resolves args.model. --- orchestrator/concurrent_executor.py | 12 ++++++++---- orchestrator/tests/test_concurrent_executor.py | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/orchestrator/concurrent_executor.py b/orchestrator/concurrent_executor.py index aea834ee72..fbac81c6c0 100644 --- a/orchestrator/concurrent_executor.py +++ b/orchestrator/concurrent_executor.py @@ -588,10 +588,14 @@ def _build_event_spawn_params( ``egg_agent.reseed.resolve_reseed_threshold`` resolves ``None`` without the ``EGG_RESEED_THRESHOLD`` override, taking the gate's ``no_threshold`` safe-reseed branch every event). It is resolved against ``claude_code_alias`` - — the same string passed to ``--model`` and the #3249 measurement, so the - injected threshold and the emitted measurement agree by construction, and - sub-1M LiteLLM models (whose bare alias carries their real-backend identity) - resolve against their real window, not the ``[1m]``-implied 1M (#3279). + — the same string passed to ``--model``. Both in-pod consumers (the reseed + gate, ``reseed.py:126-134``, and the #3249 measurement, + ``measurement.py:252-262``) read this ``EGG_RESEED_THRESHOLD`` override + first, so once it is always injected on the event path the injected + threshold and the emitted measurement agree because they read the *same env + var* — not because each independently re-resolves ``args.model``. And sub-1M + LiteLLM models (whose bare alias carries their real-backend identity) resolve + against their real window, not the ``[1m]``-implied 1M (#3279). """ decision = self._resolve_model_decision(role) command = build_consensus_wrapped_command( diff --git a/orchestrator/tests/test_concurrent_executor.py b/orchestrator/tests/test_concurrent_executor.py index 168dd2f585..0ec62fb9a0 100644 --- a/orchestrator/tests/test_concurrent_executor.py +++ b/orchestrator/tests/test_concurrent_executor.py @@ -1672,3 +1672,19 @@ def test_event_spawn_threshold_uses_real_window_for_sub_1m_model(self): env = mock_spawn.call_args.kwargs["extra_env"] assert env["EGG_RESEED_THRESHOLD"] == str(int(0.80 * 262_144)) # 209_715, NOT 400_000 + + def test_event_spawn_threshold_conservative_for_unregistered_litellm_model(self): + """An unregistered LiteLLM model (not in ``_SUB_1M_CONTEXT_MODELS``, not a + Claude alias) resolves against the conservative 200K window, so the + threshold is ``int(0.80 * 200_000)`` = ``160_000`` — the branch an operator + whose model isn't in the registry silently lands on. + """ + pipeline = _make_pipeline() + pipeline.config.agent_models = {"coder": "qwen3-coder-30b"} + mock_spawn = MagicMock(return_value=_kubernetes_spawn_result()) + spawner = self._event_spawner(pipeline, mock_spawn) + + spawner.spawn_event(role="coder", action="propose", dedupe_key="k1") + + env = mock_spawn.call_args.kwargs["extra_env"] + assert env["EGG_RESEED_THRESHOLD"] == "160000"