test_conversations.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  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. print(result)
  70. assert (
  71. exc_info.value.status_code == 404
  72. ), "Wrong error code for delete non-existent"
  73. def test_add_message_to_non_existent_conversation(client):
  74. bad_id = str(uuid.uuid4())
  75. with pytest.raises(R2RException) as exc_info:
  76. client.conversations.add_message(
  77. id=bad_id,
  78. content="Hi",
  79. role="user",
  80. )
  81. # Expected a 404 since conversation doesn't exist
  82. assert (
  83. exc_info.value.status_code == 404
  84. ), "Wrong error code for adding message to non-existent conversation"
  85. def test_update_message(client, test_conversation):
  86. # Add a message first
  87. msg_resp = client.conversations.add_message(
  88. id=test_conversation,
  89. content="Original content",
  90. role="user",
  91. )["results"]
  92. original_msg_id = msg_resp["id"]
  93. # Update the message
  94. update_resp = client.conversations.update_message(
  95. id=test_conversation,
  96. message_id=original_msg_id,
  97. content="Updated content",
  98. metadata={"new_key": "new_value"},
  99. )["results"]
  100. print(update_resp)
  101. # /new_branch_id = update_resp["new_branch_id"]
  102. assert update_resp["message"], "No message returned after update"
  103. assert update_resp["metadata"], "No metadata returned after update"
  104. assert update_resp["id"], "No metadata returned after update"
  105. # Retrieve the conversation with the new branch
  106. updated_conv = client.conversations.retrieve(id=test_conversation)[
  107. "results"
  108. ]
  109. assert updated_conv, "No conversation returned after update"
  110. assert (
  111. updated_conv[0]["message"]["content"] == "Updated content"
  112. ), "Message content not updated"
  113. # found_updated = any(msg["id"] == new_message_id and msg["message"]["content"] == "Updated content" for msg in updated_conv)
  114. # assert found_updated, "Updated message not found in the new branch"
  115. def test_update_non_existent_message(client, test_conversation):
  116. fake_msg_id = str(uuid.uuid4())
  117. with pytest.raises(R2RException) as exc_info:
  118. client.conversations.update_message(
  119. id=test_conversation, message_id=fake_msg_id, content="Should fail"
  120. )
  121. assert (
  122. exc_info.value.status_code == 404
  123. ), "Wrong error code for updating non-existent message"
  124. def test_add_message_with_empty_content(client, test_conversation):
  125. with pytest.raises(R2RException) as exc_info:
  126. client.conversations.add_message(
  127. id=test_conversation,
  128. content="", # empty content
  129. role="user",
  130. )
  131. # Check for 400 or a relevant error code depending on server validation
  132. assert (
  133. exc_info.value.status_code == 400
  134. ), "Wrong error code or no error for empty content message"
  135. def test_add_message_invalid_role(client, test_conversation):
  136. with pytest.raises(R2RException) as exc_info:
  137. client.conversations.add_message(
  138. id=test_conversation,
  139. content="Hello",
  140. role="invalid_role",
  141. )
  142. assert (
  143. exc_info.value.status_code == 400
  144. ), "Wrong error code or no error for invalid role"
  145. def test_add_message_to_deleted_conversation(client):
  146. # Create a conversation and delete it
  147. conv_id = client.conversations.create()["results"]["id"]
  148. client.conversations.delete(id=conv_id)
  149. # Try adding a message to the deleted conversation
  150. with pytest.raises(R2RException) as exc_info:
  151. client.conversations.add_message(
  152. id=conv_id,
  153. content="Should fail",
  154. role="user",
  155. )
  156. assert (
  157. exc_info.value.status_code == 404
  158. ), "Wrong error code for adding message to deleted conversation"
  159. def test_update_message_with_additional_metadata(client, test_conversation):
  160. # Add a message with initial metadata
  161. msg_resp = client.conversations.add_message(
  162. id=test_conversation,
  163. content="Initial content",
  164. role="user",
  165. metadata={"initial_key": "initial_value"},
  166. )["results"]
  167. original_msg_id = msg_resp["id"]
  168. # Update the message with new content and additional metadata
  169. update_resp = client.conversations.update_message(
  170. id=test_conversation,
  171. message_id=original_msg_id,
  172. content="Updated content",
  173. metadata={"new_key": "new_value"},
  174. )["results"]
  175. # Retrieve the conversation from the new branch
  176. updated_conv = client.conversations.retrieve(id=test_conversation)[
  177. "results"
  178. ]
  179. # Find the updated message
  180. updated_message = next(
  181. (msg for msg in updated_conv if msg["id"] == original_msg_id), None
  182. )
  183. assert (
  184. updated_message is not None
  185. ), "Updated message not found in conversation"
  186. # Check that metadata includes old keys, new keys, and 'edited': True
  187. msg_metadata = updated_message["metadata"]
  188. assert (
  189. msg_metadata.get("initial_key") == "initial_value"
  190. ), "Old metadata not preserved"
  191. assert msg_metadata.get("new_key") == "new_value", "New metadata not added"
  192. assert (
  193. msg_metadata.get("edited") is True
  194. ), "'edited' flag not set in metadata"
  195. assert (
  196. updated_message["message"]["content"] == "Updated content"
  197. ), "Message content not updated"