test_response_parsing.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import pytest
  2. from agenthub.micro.agent import parse_response as parse_response_micro
  3. from agenthub.planner_agent.prompt import parse_response as parse_response_planner
  4. from opendevin.core.exceptions import LLMResponseError
  5. from opendevin.core.utils.json import loads as custom_loads
  6. from opendevin.events.action import (
  7. FileWriteAction,
  8. MessageAction,
  9. )
  10. @pytest.mark.parametrize(
  11. 'parse_response_module',
  12. [parse_response_micro, parse_response_planner],
  13. )
  14. def test_parse_single_complete_json(parse_response_module):
  15. input_response = """
  16. {
  17. "action": "message",
  18. "args": {
  19. "content": "The following typos were fixed:\\n* 'futur' -> 'future'\\n* 'imagin' -> 'imagine'\\n* 'techological' -> 'technological'\\n* 'responsability' -> 'responsibility'\\nThe corrected file is ./short_essay.txt."
  20. }
  21. }
  22. """
  23. expected = MessageAction(
  24. "The following typos were fixed:\n* 'futur' -> 'future'\n* 'imagin' -> 'imagine'\n* 'techological' -> 'technological'\n* 'responsability' -> 'responsibility'\nThe corrected file is ./short_essay.txt."
  25. )
  26. result = parse_response_module(input_response)
  27. assert result == expected
  28. @pytest.mark.parametrize(
  29. 'parse_response_module',
  30. [parse_response_micro, parse_response_planner],
  31. )
  32. def test_parse_json_with_surrounding_text(parse_response_module):
  33. input_response = """
  34. Some initial text that is not JSON formatted.
  35. {
  36. "action": "write",
  37. "args": {
  38. "path": "./updated_file.txt",
  39. "content": "Updated text content here..."
  40. }
  41. }
  42. Some trailing text that is also not JSON formatted.
  43. """
  44. expected = FileWriteAction(
  45. path='./updated_file.txt', content='Updated text content here...'
  46. )
  47. result = parse_response_module(input_response)
  48. assert result == expected
  49. @pytest.mark.parametrize(
  50. 'parse_response_module',
  51. [parse_response_micro, parse_response_planner],
  52. )
  53. def test_parse_first_of_multiple_jsons(parse_response_module):
  54. input_response = """
  55. I will firstly do
  56. {
  57. "action": "write",
  58. "args": {
  59. "path": "./short_essay.txt",
  60. "content": "Text content here..."
  61. }
  62. }
  63. Then I will continue with
  64. {
  65. "action": "think",
  66. "args": {
  67. "thought": "This should not be parsed."
  68. }
  69. }
  70. """
  71. expected = FileWriteAction(path='./short_essay.txt', content='Text content here...')
  72. result = parse_response_module(input_response)
  73. assert result == expected
  74. def test_invalid_json_raises_error():
  75. # This should fail if repair_json is able to fix this faulty JSON
  76. input_response = '{"action": "write", "args": { "path": "./short_essay.txt", "content": "Missing closing brace" }'
  77. with pytest.raises(LLMResponseError):
  78. custom_loads(input_response)
  79. def test_no_json_found():
  80. input_response = 'This is just a string with no JSON object.'
  81. with pytest.raises(LLMResponseError):
  82. custom_loads(input_response)