diff --git a/src/praisonai/praisonai/bots/_unknown_user.py b/src/praisonai/praisonai/bots/_unknown_user.py index c0bb917fb..b739a3af4 100644 --- a/src/praisonai/praisonai/bots/_unknown_user.py +++ b/src/praisonai/praisonai/bots/_unknown_user.py @@ -132,7 +132,7 @@ async def _handle_pairing_request( owner_user_id=owner_user_id, user_name=user_name, code=code, - channel=channel, + channel=channel_type, user_id=user_id ) diff --git a/src/praisonai/praisonai/cli/session/unified.py b/src/praisonai/praisonai/cli/session/unified.py index ea46038ee..f9199fe71 100644 --- a/src/praisonai/praisonai/cli/session/unified.py +++ b/src/praisonai/praisonai/cli/session/unified.py @@ -182,8 +182,12 @@ def _get_last_session_path(self) -> Path: def _acquire_exclusive_lock(self, file_obj) -> None: if sys.platform == "win32": import msvcrt + # Lock entire file by using file size (or large value for empty files) + file_obj.seek(0, os.SEEK_END) + file_size = file_obj.tell() + lock_length = max(file_size, 1) file_obj.seek(0) - msvcrt.locking(file_obj.fileno(), msvcrt.LK_LOCK, 1) + msvcrt.locking(file_obj.fileno(), msvcrt.LK_LOCK, lock_length) elif _HAS_FCNTL: fcntl.flock(file_obj.fileno(), fcntl.LOCK_EX) else: @@ -198,8 +202,12 @@ def _acquire_exclusive_lock(self, file_obj) -> None: def _release_exclusive_lock(self, file_obj) -> None: if sys.platform == "win32": import msvcrt + # Use the same lock length as acquisition + file_obj.seek(0, os.SEEK_END) + file_size = file_obj.tell() + lock_length = max(file_size, 1) file_obj.seek(0) - msvcrt.locking(file_obj.fileno(), msvcrt.LK_UNLCK, 1) + msvcrt.locking(file_obj.fileno(), msvcrt.LK_UNLCK, lock_length) elif _HAS_FCNTL: fcntl.flock(file_obj.fileno(), fcntl.LOCK_UN) diff --git a/src/praisonai/tests/integration/bots/test_pairing_agent_e2e.py b/src/praisonai/tests/integration/bots/test_pairing_agent_e2e.py index ef2d21f02..dc046c820 100644 --- a/src/praisonai/tests/integration/bots/test_pairing_agent_e2e.py +++ b/src/praisonai/tests/integration/bots/test_pairing_agent_e2e.py @@ -117,12 +117,12 @@ async def test_unknown_dm_to_real_agent_after_owner_approval(self): # Set callback secret via environment variable for consistent signatures os.environ["PRAISONAI_CALLBACK_SECRET"] = "test-secret-for-e2e" - # Simulate owner approval using real signed callback + # Simulate owner approval using callback payload from the approval DM keyboard = PairingUIBuilder.create_telegram_keyboard( - user_name="TestUser", + user_name=approval_dm["user_name"], code=code, - channel="telegram", - user_id="new-user-1", + channel=approval_dm["channel"], + user_id=approval_dm["user_id"], ) callback_data = keyboard["inline_keyboard"][0][0]["callback_data"] # Get approve button callback @@ -191,7 +191,7 @@ async def test_pairing_flow_with_different_channels(self): assert len(self.adapter.approval_dms) == 1 approval_dm = self.adapter.approval_dms[0] - assert approval_dm["channel"] == "discord-dm-456" + assert approval_dm["channel"] == "discord" assert approval_dm["user_id"] == "discord-user-1" @pytest.mark.asyncio diff --git a/src/praisonai/tests/integration/bots/test_pairing_owner_dm.py b/src/praisonai/tests/integration/bots/test_pairing_owner_dm.py index 99caccc3c..65925bf4a 100644 --- a/src/praisonai/tests/integration/bots/test_pairing_owner_dm.py +++ b/src/praisonai/tests/integration/bots/test_pairing_owner_dm.py @@ -110,7 +110,7 @@ async def test_unknown_user_triggers_pairing_request(self): approval_dm = self.adapter.approval_dms[0] assert approval_dm["to"] == "owner-123" assert approval_dm["user_name"] == "Alice" - assert approval_dm["channel"] == "dm-123" + assert approval_dm["channel"] == "telegram" assert approval_dm["user_id"] == "new-user" # Should notify user that request was sent @@ -128,12 +128,12 @@ async def test_owner_approval_allows_future_messages(self): approval_dm = self.adapter.approval_dms[0] code = approval_dm["code"] - # Simulate owner approval using real signed callback + # Simulate owner approval using callback payload from the approval DM keyboard = PairingUIBuilder.create_telegram_keyboard( - user_name="Alice", + user_name=approval_dm["user_name"], code=code, - channel="telegram", - user_id="new-user", + channel=approval_dm["channel"], + user_id=approval_dm["user_id"], ) callback_data = keyboard["inline_keyboard"][0][0]["callback_data"] # Get approve button callback