import uuid import pytest from r2r import R2RClient, R2RException @pytest.fixture def test_conversation(client): """Create and yield a test conversation, then clean up.""" conv_resp = client.conversations.create() conversation_id = conv_resp["results"]["id"] yield conversation_id # Cleanup: Try deleting the conversation if it still exists try: client.conversations.delete(id=conversation_id) except R2RException: pass def test_create_conversation(client): resp = client.conversations.create()["results"] conv_id = resp["id"] assert conv_id is not None, "No conversation_id returned" # Cleanup client.conversations.delete(id=conv_id) def test_list_conversations(client, test_conversation): listed = client.conversations.list(offset=0, limit=10) results = listed["results"] # Just ensure at least one conversation is listed assert len(results) >= 1, "Expected at least one conversation, none found" def test_retrieve_conversation(client, test_conversation): # Retrieve the conversation just created retrieved = client.conversations.retrieve(id=test_conversation)["results"] # A new conversation might have no messages, so results should be an empty list assert isinstance(retrieved, list), "Expected list of messages" assert ( len(retrieved) == 0 ), "Expected empty message list for a new conversation" def test_delete_conversation(client): # Create a conversation and delete it conv = client.conversations.create()["results"] conv_id = conv["id"] client.conversations.delete(id=conv_id) # Verify retrieval fails with pytest.raises(R2RException) as exc_info: client.conversations.retrieve(id=conv_id) assert ( exc_info.value.status_code == 404 ), "Wrong error code retrieving deleted conversation" def test_add_message(client, test_conversation): # Add a message to the conversation msg_resp = client.conversations.add_message( id=test_conversation, content="Hello", role="user", )["results"] msg_id = msg_resp["id"] assert msg_id, "No message ID returned after adding a message" # Retrieve conversation and verify message is present retrieved = client.conversations.retrieve(id=test_conversation)["results"] found = any(msg["id"] == msg_id for msg in retrieved) assert found, "Added message not found in conversation" def test_retrieve_non_existent_conversation(client): bad_id = str(uuid.uuid4()) with pytest.raises(R2RException) as exc_info: client.conversations.retrieve(id=bad_id) assert ( exc_info.value.status_code == 404 ), "Wrong error code for non-existent conversation" def test_delete_non_existent_conversation(client): bad_id = str(uuid.uuid4()) with pytest.raises(R2RException) as exc_info: result = client.conversations.delete(id=bad_id) print(result) assert ( exc_info.value.status_code == 404 ), "Wrong error code for delete non-existent" def test_add_message_to_non_existent_conversation(client): bad_id = str(uuid.uuid4()) with pytest.raises(R2RException) as exc_info: client.conversations.add_message( id=bad_id, content="Hi", role="user", ) # Expected a 404 since conversation doesn't exist assert ( exc_info.value.status_code == 404 ), "Wrong error code for adding message to non-existent conversation" def test_update_message(client, test_conversation): # Add a message first msg_resp = client.conversations.add_message( id=test_conversation, content="Original content", role="user", )["results"] original_msg_id = msg_resp["id"] # Update the message update_resp = client.conversations.update_message( id=test_conversation, message_id=original_msg_id, content="Updated content", metadata={"new_key": "new_value"}, )["results"] print(update_resp) # /new_branch_id = update_resp["new_branch_id"] assert update_resp["message"], "No message returned after update" assert update_resp["metadata"], "No metadata returned after update" assert update_resp["id"], "No metadata returned after update" # Retrieve the conversation with the new branch updated_conv = client.conversations.retrieve(id=test_conversation)[ "results" ] assert updated_conv, "No conversation returned after update" assert ( updated_conv[0]["message"]["content"] == "Updated content" ), "Message content not updated" # found_updated = any(msg["id"] == new_message_id and msg["message"]["content"] == "Updated content" for msg in updated_conv) # assert found_updated, "Updated message not found in the new branch" def test_update_non_existent_message(client, test_conversation): fake_msg_id = str(uuid.uuid4()) with pytest.raises(R2RException) as exc_info: client.conversations.update_message( id=test_conversation, message_id=fake_msg_id, content="Should fail" ) assert ( exc_info.value.status_code == 404 ), "Wrong error code for updating non-existent message" def test_add_message_with_empty_content(client, test_conversation): with pytest.raises(R2RException) as exc_info: client.conversations.add_message( id=test_conversation, content="", # empty content role="user", ) # Check for 400 or a relevant error code depending on server validation assert ( exc_info.value.status_code == 400 ), "Wrong error code or no error for empty content message" def test_add_message_invalid_role(client, test_conversation): with pytest.raises(R2RException) as exc_info: client.conversations.add_message( id=test_conversation, content="Hello", role="invalid_role", ) assert ( exc_info.value.status_code == 400 ), "Wrong error code or no error for invalid role" def test_add_message_to_deleted_conversation(client): # Create a conversation and delete it conv_id = client.conversations.create()["results"]["id"] client.conversations.delete(id=conv_id) # Try adding a message to the deleted conversation with pytest.raises(R2RException) as exc_info: client.conversations.add_message( id=conv_id, content="Should fail", role="user", ) assert ( exc_info.value.status_code == 404 ), "Wrong error code for adding message to deleted conversation" def test_update_message_with_additional_metadata(client, test_conversation): # Add a message with initial metadata msg_resp = client.conversations.add_message( id=test_conversation, content="Initial content", role="user", metadata={"initial_key": "initial_value"}, )["results"] original_msg_id = msg_resp["id"] # Update the message with new content and additional metadata update_resp = client.conversations.update_message( id=test_conversation, message_id=original_msg_id, content="Updated content", metadata={"new_key": "new_value"}, )["results"] # Retrieve the conversation from the new branch updated_conv = client.conversations.retrieve(id=test_conversation)[ "results" ] # Find the updated message updated_message = next( (msg for msg in updated_conv if msg["id"] == original_msg_id), None ) assert ( updated_message is not None ), "Updated message not found in conversation" # Check that metadata includes old keys, new keys, and 'edited': True msg_metadata = updated_message["metadata"] assert ( msg_metadata.get("initial_key") == "initial_value" ), "Old metadata not preserved" assert msg_metadata.get("new_key") == "new_value", "New metadata not added" assert ( msg_metadata.get("edited") is True ), "'edited' flag not set in metadata" assert ( updated_message["message"]["content"] == "Updated content" ), "Message content not updated"