fix(#4251): preserve raced picker ownership through profile repair
This commit is contained in:
1 parent
160a397c48
commit
5c7ff9c70e
2 files changed
+34
-5
No files matched your search
+3
-1
@@ -6695,6 +6695,7 @@ def _run_agent_streaming(
|
||||
update_active_run(stream_id, phase="running", session_id=session_id)
|
||||
s.workspace = str(Path(workspace).expanduser().resolve())
|
||||
_last_persisted_model = getattr(s, "model", None)
|
||||
_turn_owns_persisted_model = False
|
||||
provider_context = (
|
||||
str(model_provider).strip().lower()
|
||||
if model_provider is not None
|
||||
@@ -6707,6 +6708,7 @@ def _run_agent_streaming(
|
||||
s.model = model
|
||||
s.model_provider = provider_context or None
|
||||
_last_persisted_model = model
|
||||
_turn_owns_persisted_model = True
|
||||
|
||||
_agent_lock = _get_session_agent_lock(session_id)
|
||||
# TD1: set thread-local env context so concurrent sessions don't clobber globals
|
||||
@@ -6750,7 +6752,7 @@ def _run_agent_streaming(
|
||||
)
|
||||
# #4251: only apply the profile-repair persistence if this turn still
|
||||
# owns the session model value it last wrote.
|
||||
if getattr(s, "model", None) == _last_persisted_model:
|
||||
if _turn_owns_persisted_model and getattr(s, "model", None) == _last_persisted_model:
|
||||
s.model_provider = provider_context
|
||||
if _repaired and model != (s.model or ""):
|
||||
s.model = model
|
||||
|
||||
@@ -134,7 +134,14 @@ def _install_streaming_harness(monkeypatch, fake_session):
|
||||
monkeypatch.setitem(sys.modules, "hermes_state", fake_hermes_state)
|
||||
|
||||
|
||||
def _run_streaming_turn(monkeypatch, fake_session, *, stream_id):
|
||||
def _run_streaming_turn(
|
||||
monkeypatch,
|
||||
fake_session,
|
||||
*,
|
||||
stream_id,
|
||||
dispatch_model="haiku-4-5",
|
||||
dispatch_provider="anthropic",
|
||||
):
|
||||
_install_streaming_harness(monkeypatch, fake_session)
|
||||
fake_session.active_stream_id = stream_id
|
||||
fake_queue = queue.Queue()
|
||||
@@ -143,8 +150,8 @@ def _run_streaming_turn(monkeypatch, fake_session, *, stream_id):
|
||||
streaming._run_agent_streaming(
|
||||
session_id=fake_session.session_id,
|
||||
msg_text="background wakeup turn",
|
||||
model="haiku-4-5",
|
||||
model_provider="anthropic",
|
||||
model=dispatch_model,
|
||||
model_provider=dispatch_provider,
|
||||
workspace="/tmp",
|
||||
stream_id=stream_id,
|
||||
)
|
||||
@@ -154,7 +161,7 @@ def _run_streaming_turn(monkeypatch, fake_session, *, stream_id):
|
||||
|
||||
|
||||
def test_dispatch_stamp_does_not_clobber_newer_picker_model(monkeypatch):
|
||||
fake_session = FakeSession(model="opus-4-8", model_provider="anthropic")
|
||||
fake_session = FakeSession(model="opus-4-8", model_provider="openrouter")
|
||||
|
||||
_run_streaming_turn(
|
||||
monkeypatch,
|
||||
@@ -163,6 +170,7 @@ def test_dispatch_stamp_does_not_clobber_newer_picker_model(monkeypatch):
|
||||
)
|
||||
|
||||
assert fake_session.model == "opus-4-8"
|
||||
assert fake_session.model_provider == "openrouter"
|
||||
|
||||
|
||||
def test_dispatch_stamp_persists_resolved_model_when_no_race(monkeypatch):
|
||||
@@ -189,3 +197,22 @@ def test_dispatch_stamp_persists_when_session_model_was_empty(monkeypatch):
|
||||
|
||||
assert fake_session.model == "haiku-4-5"
|
||||
assert fake_session.model_provider == "anthropic"
|
||||
|
||||
|
||||
def test_profile_repair_skips_persistence_when_newer_picker_choice_already_won(monkeypatch):
|
||||
fake_session = FakeSession(model="opus-4-8", model_provider="openrouter")
|
||||
fake_session.profile = "worker-profile"
|
||||
monkeypatch.setattr(
|
||||
streaming,
|
||||
"_apply_profile_home_context_to_streaming_model",
|
||||
lambda **_kwargs: ("claude-profile-default", "anthropic", True),
|
||||
)
|
||||
|
||||
_run_streaming_turn(
|
||||
monkeypatch,
|
||||
fake_session,
|
||||
stream_id="stream-4251-profile-race",
|
||||
)
|
||||
|
||||
assert fake_session.model == "opus-4-8"
|
||||
assert fake_session.model_provider == "openrouter"
|
||||
Reference in new issue
Block a user