Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion loopx/attached_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,10 @@ def _require_attached_host(
session_id: str,
host_surface: str,
host_session_id: str,
allow_closed: bool = False,
) -> dict[str, Any]:
session = store.load_session(session_id)
if session is None or session.get("status") == "closed":
if session is None or (session.get("status") == "closed" and not allow_closed):
raise KeyError("attached Agent session was not found")
if session.get("session_mode") != CHAT_SESSION_MODE_ATTACHED:
raise ValueError("the selected Session is not an attached host session")
Expand Down Expand Up @@ -273,6 +274,7 @@ def complete_attached_agent_turn(
session_id=session_id,
host_surface=host_surface,
host_session_id=host_session_id,
allow_closed=True,
)
normalized_response = normalize_agent_response(
response,
Expand Down
37 changes: 37 additions & 0 deletions tests/test_attached_session_broker.py
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,43 @@ def test_attached_close_rejects_active_claim_and_preserves_completion(
assert runtime.wait_for_turn(session_id=session_id, turn_id=turn_id)["status"] == "completed"
assert runtime.close_session(session_id) is True
assert store.load_session(session_id)["status"] == "closed" # type: ignore[index]
with pytest.raises(KeyError, match="attached Agent session was not found"):
claim_attached_agent_turn(
store=store,
session_id=session_id,
host_surface=HOST_SURFACE,
host_session_id=HOST_SESSION_ID,
claim_id="claim-after-close",
)

replay = complete_attached_agent_turn(
store=store,
session_id=session_id,
turn_id=turn_id,
host_surface=HOST_SURFACE,
host_session_id=HOST_SESSION_ID,
claim_id="close-active-claim",
completion_id="close-active-completion",
response={"message": "retry payload"},
)

assert replay["created"] is False
assert [
message["text"]
for message in store.messages(session_id)
if message["role"] == "agent"
] == ["completed before close"]
with pytest.raises(ValueError, match="already completed by another receipt"):
complete_attached_agent_turn(
store=store,
session_id=session_id,
turn_id=turn_id,
host_surface=HOST_SURFACE,
host_session_id=HOST_SESSION_ID,
claim_id="close-active-claim",
completion_id="different-receipt",
response={"message": "conflicting retry"},
)


def test_attached_close_rejects_pending_queue_and_preserves_claimability(
Expand Down