test_conversations.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. import uuid
  2. import pytest
  3. from r2r import R2RClient, R2RException
  4. @pytest.fixture
  5. def test_conversation(client):
  6. """Create and yield a test conversation, then clean up."""
  7. conv_resp = client.conversations.create()
  8. conversation_id = conv_resp["results"]["id"]
  9. yield conversation_id
  10. # Cleanup: Try deleting the conversation if it still exists
  11. try:
  12. client.conversations.delete(id=conversation_id)
  13. except R2RException:
  14. pass
  15. def test_create_conversation(client):
  16. resp = client.conversations.create()["results"]
  17. conv_id = resp["id"]
  18. assert conv_id is not None, "No conversation_id returned"
  19. # Cleanup
  20. client.conversations.delete(id=conv_id)
  21. def test_list_conversations(client, test_conversation):
  22. listed = client.conversations.list(offset=0, limit=10)
  23. results = listed["results"]
  24. # Just ensure at least one conversation is listed
  25. assert len(results) >= 1, "Expected at least one conversation, none found"
  26. def test_retrieve_conversation(client, test_conversation):
  27. # Retrieve the conversation just created
  28. retrieved = client.conversations.retrieve(id=test_conversation)["results"]
  29. # A new conversation might have no messages, so results should be an empty list
  30. assert isinstance(retrieved, list), "Expected list of messages"
  31. assert (
  32. len(retrieved) == 0
  33. ), "Expected empty message list for a new conversation"
  34. def test_delete_conversation(client):
  35. # Create a conversation and delete it
  36. conv = client.conversations.create()["results"]
  37. conv_id = conv["id"]
  38. client.conversations.delete(id=conv_id)
  39. # Verify retrieval fails
  40. with pytest.raises(R2RException) as exc_info:
  41. client.conversations.retrieve(id=conv_id)
  42. assert (
  43. exc_info.value.status_code == 404
  44. ), "Wrong error code retrieving deleted conversation"
  45. def test_add_message(client, test_conversation):
  46. # Add a message to the conversation
  47. msg_resp = client.conversations.add_message(
  48. id=test_conversation,
  49. content="Hello",
  50. role="user",
  51. )["results"]
  52. msg_id = msg_resp["id"]
  53. assert msg_id, "No message ID returned after adding a message"
  54. # Retrieve conversation and verify message is present
  55. retrieved = client.conversations.retrieve(id=test_conversation)["results"]
  56. found = any(msg["id"] == msg_id for msg in retrieved)
  57. assert found, "Added message not found in conversation"
  58. def test_retrieve_non_existent_conversation(client):
  59. bad_id = str(uuid.uuid4())
  60. with pytest.raises(R2RException) as exc_info:
  61. client.conversations.retrieve(id=bad_id)
  62. assert (
  63. exc_info.value.status_code == 404
  64. ), "Wrong error code for non-existent conversation"
  65. def test_delete_non_existent_conversation(client):
  66. bad_id = str(uuid.uuid4())
  67. with pytest.raises(R2RException) as exc_info:
  68. result = client.conversations.delete(id=bad_id)
  69. assert (
  70. exc_info.value.status_code == 404
  71. ), "Wrong error code for delete non-existent"
  72. def test_add_message_to_non_existent_conversation(client):
  73. bad_id = str(uuid.uuid4())
  74. with pytest.raises(R2RException) as exc_info:
  75. client.conversations.add_message(
  76. id=bad_id,
  77. content="Hi",
  78. role="user",
  79. )
  80. # Expected a 404 since conversation doesn't exist
  81. assert (
  82. exc_info.value.status_code == 404
  83. ), "Wrong error code for adding message to non-existent conversation"
  84. def test_update_message(client, test_conversation):
  85. # Add a message first
  86. msg_resp = client.conversations.add_message(
  87. id=test_conversation,
  88. content="Original content",
  89. role="user",
  90. )["results"]
  91. original_msg_id = msg_resp["id"]
  92. # Update the message
  93. update_resp = client.conversations.update_message(
  94. id=test_conversation,
  95. message_id=original_msg_id,
  96. content="Updated content",
  97. metadata={"new_key": "new_value"},
  98. )["results"]
  99. # /new_branch_id = update_resp["new_branch_id"]
  100. assert update_resp["message"], "No message returned after update"
  101. assert update_resp["metadata"], "No metadata returned after update"
  102. assert update_resp["id"], "No metadata returned after update"
  103. # Retrieve the conversation with the new branch
  104. updated_conv = client.conversations.retrieve(id=test_conversation)[
  105. "results"
  106. ]
  107. assert updated_conv, "No conversation returned after update"
  108. assert (
  109. updated_conv[0]["message"]["content"] == "Updated content"
  110. ), "Message content not updated"
  111. # found_updated = any(msg["id"] == new_message_id and msg["message"]["content"] == "Updated content" for msg in updated_conv)
  112. # assert found_updated, "Updated message not found in the new branch"
  113. def test_update_non_existent_message(client, test_conversation):
  114. fake_msg_id = str(uuid.uuid4())
  115. with pytest.raises(R2RException) as exc_info:
  116. client.conversations.update_message(
  117. id=test_conversation, message_id=fake_msg_id, content="Should fail"
  118. )
  119. assert (
  120. exc_info.value.status_code == 404
  121. ), "Wrong error code for updating non-existent message"
  122. def test_add_message_with_empty_content(client, test_conversation):
  123. with pytest.raises(R2RException) as exc_info:
  124. client.conversations.add_message(
  125. id=test_conversation,
  126. content="", # empty content
  127. role="user",
  128. )
  129. # Check for 400 or a relevant error code depending on server validation
  130. assert (
  131. exc_info.value.status_code == 400
  132. ), "Wrong error code or no error for empty content message"
  133. def test_add_message_invalid_role(client, test_conversation):
  134. with pytest.raises(R2RException) as exc_info:
  135. client.conversations.add_message(
  136. id=test_conversation,
  137. content="Hello",
  138. role="invalid_role",
  139. )
  140. assert (
  141. exc_info.value.status_code == 400
  142. ), "Wrong error code or no error for invalid role"
  143. def test_add_message_to_deleted_conversation(client):
  144. # Create a conversation and delete it
  145. conv_id = client.conversations.create()["results"]["id"]
  146. client.conversations.delete(id=conv_id)
  147. # Try adding a message to the deleted conversation
  148. with pytest.raises(R2RException) as exc_info:
  149. client.conversations.add_message(
  150. id=conv_id,
  151. content="Should fail",
  152. role="user",
  153. )
  154. assert (
  155. exc_info.value.status_code == 404
  156. ), "Wrong error code for adding message to deleted conversation"
  157. def test_update_message_with_additional_metadata(client, test_conversation):
  158. # Add a message with initial metadata
  159. msg_resp = client.conversations.add_message(
  160. id=test_conversation,
  161. content="Initial content",
  162. role="user",
  163. metadata={"initial_key": "initial_value"},
  164. )["results"]
  165. original_msg_id = msg_resp["id"]
  166. # Update the message with new content and additional metadata
  167. update_resp = client.conversations.update_message(
  168. id=test_conversation,
  169. message_id=original_msg_id,
  170. content="Updated content",
  171. metadata={"new_key": "new_value"},
  172. )["results"]
  173. # Retrieve the conversation from the new branch
  174. updated_conv = client.conversations.retrieve(id=test_conversation)[
  175. "results"
  176. ]
  177. # Find the updated message
  178. updated_message = next(
  179. (msg for msg in updated_conv if msg["id"] == original_msg_id), None
  180. )
  181. assert (
  182. updated_message is not None
  183. ), "Updated message not found in conversation"
  184. # Check that metadata includes old keys, new keys, and 'edited': True
  185. msg_metadata = updated_message["metadata"]
  186. assert (
  187. msg_metadata.get("initial_key") == "initial_value"
  188. ), "Old metadata not preserved"
  189. assert msg_metadata.get("new_key") == "new_value", "New metadata not added"
  190. assert (
  191. msg_metadata.get("edited") is True
  192. ), "'edited' flag not set in metadata"
  193. assert (
  194. updated_message["message"]["content"] == "Updated content"
  195. ), "Message content not updated"