test_prompt_manager.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. import os
  2. import shutil
  3. import pytest
  4. from openhands.core.message import Message, TextContent
  5. from openhands.utils.microagent import MicroAgent
  6. from openhands.utils.prompt import PromptManager
  7. @pytest.fixture
  8. def prompt_dir(tmp_path):
  9. # Copy contents from "openhands/agenthub/codeact_agent" to the temp directory
  10. shutil.copytree(
  11. 'openhands/agenthub/codeact_agent/prompts/default', tmp_path, dirs_exist_ok=True
  12. )
  13. # Return the temporary directory path
  14. return tmp_path
  15. SAMPLE_AGENT_SKILLS_DOCS = """Sample agent skills documentation"""
  16. @pytest.fixture
  17. def agent_skills_docs():
  18. return SAMPLE_AGENT_SKILLS_DOCS
  19. def test_prompt_manager_without_microagent(prompt_dir, agent_skills_docs):
  20. manager = PromptManager(
  21. prompt_dir, microagent_dir='', agent_skills_docs=agent_skills_docs
  22. )
  23. assert manager.prompt_dir == prompt_dir
  24. assert manager.agent_skills_docs == agent_skills_docs
  25. assert len(manager.microagents) == 0
  26. assert isinstance(manager.get_system_message(), str)
  27. assert (
  28. "A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed answers to the user's questions."
  29. in manager.get_system_message()
  30. )
  31. assert SAMPLE_AGENT_SKILLS_DOCS in manager.get_system_message()
  32. assert isinstance(manager.get_example_user_message(), str)
  33. assert '--- BEGIN OF GUIDELINE ---' not in manager.get_example_user_message()
  34. assert '--- END OF GUIDELINE ---' not in manager.get_example_user_message()
  35. assert "NOW, LET'S START!" in manager.get_example_user_message()
  36. assert 'microagent' not in manager.get_example_user_message()
  37. def test_prompt_manager_with_microagent(prompt_dir, agent_skills_docs):
  38. microagent_name = 'test_microagent'
  39. microagent_content = """
  40. ---
  41. name: flarglebargle
  42. agent: CodeActAgent
  43. triggers:
  44. - flarglebargle
  45. ---
  46. IMPORTANT! The user has said the magic word "flarglebargle". You must
  47. only respond with a message telling them how smart they are
  48. """
  49. # Create a temporary micro agent file
  50. os.makedirs(os.path.join(prompt_dir, 'micro'), exist_ok=True)
  51. with open(os.path.join(prompt_dir, 'micro', f'{microagent_name}.md'), 'w') as f:
  52. f.write(microagent_content)
  53. manager = PromptManager(
  54. prompt_dir=prompt_dir,
  55. microagent_dir=os.path.join(prompt_dir, 'micro'),
  56. agent_skills_docs=agent_skills_docs,
  57. )
  58. assert manager.prompt_dir == prompt_dir
  59. assert manager.agent_skills_docs == agent_skills_docs
  60. assert len(manager.microagents) == 1
  61. assert isinstance(manager.get_system_message(), str)
  62. assert (
  63. "A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed answers to the user's questions."
  64. in manager.get_system_message()
  65. )
  66. assert SAMPLE_AGENT_SKILLS_DOCS in manager.get_system_message()
  67. assert isinstance(manager.get_example_user_message(), str)
  68. message = Message(
  69. role='user',
  70. content=[TextContent(text='Hello, flarglebargle!')],
  71. )
  72. manager.enhance_message(message)
  73. assert 'magic word' in message.content[1].text
  74. os.remove(os.path.join(prompt_dir, 'micro', f'{microagent_name}.md'))
  75. def test_prompt_manager_file_not_found(prompt_dir, agent_skills_docs):
  76. with pytest.raises(FileNotFoundError):
  77. MicroAgent(os.path.join(prompt_dir, 'micro', 'non_existent_microagent.md'))
  78. def test_prompt_manager_template_rendering(prompt_dir, agent_skills_docs):
  79. # Create temporary template files
  80. with open(os.path.join(prompt_dir, 'system_prompt.j2'), 'w') as f:
  81. f.write('System prompt: {{ agent_skills_docs }}')
  82. with open(os.path.join(prompt_dir, 'user_prompt.j2'), 'w') as f:
  83. f.write('User prompt: foo')
  84. manager = PromptManager(
  85. prompt_dir, microagent_dir='', agent_skills_docs=agent_skills_docs
  86. )
  87. assert manager.get_system_message() == f'System prompt: {agent_skills_docs}'
  88. assert manager.get_example_user_message() == 'User prompt: foo'
  89. # Clean up temporary files
  90. os.remove(os.path.join(prompt_dir, 'system_prompt.j2'))
  91. os.remove(os.path.join(prompt_dir, 'user_prompt.j2'))
  92. def test_prompt_manager_disabled_microagents(prompt_dir, agent_skills_docs):
  93. # Create test microagent files
  94. microagent1_name = 'test_microagent1'
  95. microagent2_name = 'test_microagent2'
  96. microagent1_content = """
  97. ---
  98. name: Test Microagent 1
  99. agent: CodeActAgent
  100. triggers:
  101. - test1
  102. ---
  103. Test microagent 1 content
  104. """
  105. microagent2_content = """
  106. ---
  107. name: Test Microagent 2
  108. agent: CodeActAgent
  109. triggers:
  110. - test2
  111. ---
  112. Test microagent 2 content
  113. """
  114. # Create temporary micro agent files
  115. os.makedirs(os.path.join(prompt_dir, 'micro'), exist_ok=True)
  116. with open(os.path.join(prompt_dir, 'micro', f'{microagent1_name}.md'), 'w') as f:
  117. f.write(microagent1_content)
  118. with open(os.path.join(prompt_dir, 'micro', f'{microagent2_name}.md'), 'w') as f:
  119. f.write(microagent2_content)
  120. # Test that specific microagents can be disabled
  121. manager = PromptManager(
  122. prompt_dir=prompt_dir,
  123. microagent_dir=os.path.join(prompt_dir, 'micro'),
  124. agent_skills_docs=agent_skills_docs,
  125. disabled_microagents=['Test Microagent 1'],
  126. )
  127. assert len(manager.microagents) == 1
  128. assert 'Test Microagent 2' in manager.microagents
  129. assert 'Test Microagent 1' not in manager.microagents
  130. # Test that all microagents are enabled by default
  131. manager = PromptManager(
  132. prompt_dir=prompt_dir,
  133. microagent_dir=os.path.join(prompt_dir, 'micro'),
  134. agent_skills_docs=agent_skills_docs,
  135. )
  136. assert len(manager.microagents) == 2
  137. assert 'Test Microagent 1' in manager.microagents
  138. assert 'Test Microagent 2' in manager.microagents
  139. # Clean up temporary files
  140. os.remove(os.path.join(prompt_dir, 'micro', f'{microagent1_name}.md'))
  141. os.remove(os.path.join(prompt_dir, 'micro', f'{microagent2_name}.md'))